├── Makefile ├── README.md ├── criterion_tests └── e1ap │ ├── components │ ├── drb │ │ ├── Makefile │ │ ├── cuup.c │ │ ├── cuup.h │ │ ├── drb.c │ │ ├── drb.h │ │ ├── e1ap_bearer_modify.h │ │ ├── e1ap_bearer_setup.h │ │ ├── e1ap_comm.h │ │ ├── fixes │ │ ├── pfm.c │ │ ├── pfm.h │ │ ├── pfm_comm.h │ │ ├── pfm_log.c │ │ ├── pfm_log.h │ │ ├── pfm_utils.c │ │ ├── pfm_utils.h │ │ ├── run.sh │ │ ├── test.c │ │ ├── test_custom.c │ │ ├── tunnel.c │ │ ├── tunnel.h │ │ ├── ue_ctx.c │ │ └── ue_ctx.h │ ├── pdus │ │ ├── Makefile │ │ ├── cuup.c │ │ ├── cuup.h │ │ ├── drb.c │ │ ├── drb.h │ │ ├── e1ap_bearer_modify.h │ │ ├── e1ap_bearer_setup.h │ │ ├── e1ap_comm.h │ │ ├── fixes │ │ ├── pdus.c │ │ ├── pdus.h │ │ ├── pfm.c │ │ ├── pfm.h │ │ ├── pfm_comm.h │ │ ├── pfm_log.c │ │ ├── pfm_log.h │ │ ├── pfm_utils.c │ │ ├── pfm_utils.h │ │ ├── run.sh │ │ ├── test.c │ │ ├── tunnel.c │ │ ├── tunnel.h │ │ ├── ue_ctx.c │ │ └── ue_ctx.h │ ├── tunnel │ │ ├── Makefile │ │ ├── cuup.c │ │ ├── cuup.h │ │ ├── fixes │ │ ├── pfm.c │ │ ├── pfm.h │ │ ├── pfm_comm.h │ │ ├── pfm_log.c │ │ ├── pfm_log.h │ │ ├── pfm_utils.c │ │ ├── pfm_utils.h │ │ ├── run.sh │ │ ├── test.c │ │ ├── test_custom.c │ │ ├── tunnel.c │ │ └── tunnel.h │ └── ue_ctx │ │ ├── Makefile │ │ ├── cuup.c │ │ ├── cuup.h │ │ ├── drb.c │ │ ├── drb.h │ │ ├── e1ap_bearer_setup.c │ │ ├── e1ap_bearer_setup.h │ │ ├── e1ap_comm.h │ │ ├── ipcmd.txt │ │ ├── pdus.c │ │ ├── pdus.h │ │ ├── pfm.c │ │ ├── pfm.h │ │ ├── pfm_comm.h │ │ ├── pfm_log.c │ │ ├── pfm_log.h │ │ ├── pfm_utils.c │ │ ├── pfm_utils.h │ │ ├── run.sh │ │ ├── test.c │ │ ├── tunnel.c │ │ ├── tunnel.h │ │ ├── ue_ctx.c │ │ └── ue_ctx.h │ └── e1ap_bearer_setup │ ├── Makefile │ ├── cuup.c │ ├── cuup.h │ ├── drb.c │ ├── drb.h │ ├── e1ap_bearer_setup.c │ ├── e1ap_bearer_setup.h │ ├── e1ap_comm.h │ ├── ipcmd.txt │ ├── pdus.c │ ├── pdus.h │ ├── pfm.c │ ├── pfm.h │ ├── pfm_comm.h │ ├── pfm_log.c │ ├── pfm_log.h │ ├── pfm_utils.c │ ├── pfm_utils.h │ ├── run.sh │ ├── tunnel.c │ ├── tunnel.h │ ├── ue_ctx.c │ └── ue_ctx.h ├── cuup.c ├── cuup.h ├── drb.c ├── drb.h ├── e1ap_bearer_modify.c ├── e1ap_bearer_modify.h ├── e1ap_bearer_release.c ├── e1ap_bearer_release.h ├── e1ap_bearer_setup.c ├── e1ap_bearer_setup.h ├── e1ap_comm.h ├── e1ap_error_indication.c ├── e1ap_error_indication.h ├── gtp.c ├── gtp.h ├── gtp.md ├── ipcmd.txt ├── pdcp.c ├── pdcp.h ├── pdus.c ├── pdus.h ├── pfm.c ├── pfm.h ├── pfm_arp.c ├── pfm_arp.h ├── pfm_classifier.c ├── pfm_classifier.h ├── pfm_cli.c ├── pfm_cli.h ├── pfm_comm.h ├── pfm_dist_loop.c ├── pfm_dist_loop.h ├── pfm_kni.c ├── pfm_kni.h ├── pfm_link.c ├── pfm_link.h ├── pfm_log.c ├── pfm_log.h ├── pfm_ring.c ├── pfm_ring.h ├── pfm_route.c ├── pfm_route.h ├── pfm_rx_loop.c ├── pfm_rx_loop.h ├── pfm_tx_loop.c ├── pfm_tx_loop.h ├── pfm_utils.c ├── pfm_utils.h ├── pfm_worker_loop.c ├── pfm_worker_loop.h ├── pics └── PFM_architecture.png ├── run.sh ├── sdap.c ├── sdap.h ├── test ├── F1u.edpat ├── GTP.edpat ├── NGu.edpat ├── addr.edpat ├── arp.edpat ├── echo.edpat ├── gtp.edpat ├── gtp_main.edpat └── pfm_arp_test │ ├── addr.edpat │ └── pfm_arp_test1.edpat ├── tunnel.c ├── tunnel.h ├── ue_ctx.c ├── ue_ctx.h └── unittests ├── arp ├── .main.c.swp ├── Makefile ├── cuup.c ├── main.c ├── pfm.c ├── pfm.h ├── pfm_arp.c ├── pfm_arp.h ├── pfm_comm.h ├── pfm_link.c ├── pfm_link.h ├── pfm_log.c └── pfm_log.h ├── hash ├── Makefile └── hash_unit_test.c └── route ├── Makefile ├── main.c ├── pfm.h ├── pfm_comm.h ├── pfm_log.c ├── pfm_log.h ├── pfm_route.c ├── pfm_route.h ├── pfm_utils.c └── pfm_utils.h /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2010-2014 Intel Corporation 3 | 4 | # binary name 5 | APP = cuup.exe 6 | 7 | # all source are stored in SRCS-y 8 | SRCS-y := cuup.c \ 9 | pfm.c \ 10 | pfm_log.c \ 11 | pfm_worker_loop.c \ 12 | pfm_link.c \ 13 | pfm_rx_loop.c \ 14 | pfm_tx_loop.c \ 15 | pfm_kni.c \ 16 | pfm_ring.c \ 17 | pfm_classifier.c \ 18 | pfm_dist_loop.c \ 19 | pfm_route.c \ 20 | pfm_arp.c \ 21 | pfm_cli.c \ 22 | pfm_utils.c \ 23 | ue_ctx.c \ 24 | tunnel.c \ 25 | pdus.c \ 26 | drb.c \ 27 | e1ap_bearer_setup.c \ 28 | e1ap_bearer_modify.c \ 29 | e1ap_bearer_release.c \ 30 | gtp.c \ 31 | pdcp.c \ 32 | sdap.c \ 33 | 34 | 35 | # Build using pkg-config variables if possible 36 | ifeq ($(shell pkg-config --exists libdpdk && echo 0),0) 37 | 38 | all: shared 39 | .PHONY: shared static 40 | shared: build/$(APP)-shared 41 | ln -sf $(APP)-shared build/$(APP) 42 | static: build/$(APP)-static 43 | ln -sf $(APP)-static build/$(APP) 44 | 45 | PKGCONF ?= pkg-config 46 | 47 | PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) 48 | CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) 49 | CFLAGS += -DALLOW_EXPERIMENTAL_API 50 | LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) 51 | LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) 52 | 53 | build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build 54 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 55 | 56 | build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build 57 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) 58 | 59 | build: 60 | @mkdir -p $@ 61 | 62 | .PHONY: clean 63 | clean: 64 | rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared 65 | test -d build && rmdir -p build || true 66 | 67 | else # Build using legacy build system 68 | 69 | ifeq ($(RTE_SDK),) 70 | $(error "Please define RTE_SDK environment variable") 71 | endif 72 | 73 | # Default target, detect a build directory, by looking for a path with a .config 74 | RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) 75 | 76 | include $(RTE_SDK)/mk/rte.vars.mk 77 | 78 | ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),y) 79 | $(error This application can only operate in a linux environment, \ 80 | please change the definition of the RTE_TARGET environment variable) 81 | endif 82 | 83 | #CFLAGS += -O3 -g -DTRACE -DCONSLOG 84 | CFLAGS += -O3 -g -DTRACE 85 | CFLAGS += -DALLOW_EXPERIMENTAL_API 86 | CFLAGS += $(WERROR_FLAGS) 87 | 88 | include $(RTE_SDK)/mk/rte.extapp.mk 89 | endif 90 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PFM 2 | 3 | PFM is a prototype of gNB-CU-UP a network element in teh 5G Radio Access Network. It make use of DPDK for User-Plane Packet Processing 4 | and Includes a Platform software that can be used as a framework to build other network elements on, the platform software handles important 5 | features like ARP, Routing tables and multi-thread support. 6 | 7 | ## PFM Features 8 | 9 | - ARP support for DPDK interfaces. 10 | - KNI Integration. 11 | - Routing tables using Longest Prefix match. 12 | - Multi thread support using rte\_distributor. 13 | - Communication between threads using rte\_ring structures. 14 | - GPRS Tunneling Protocol implementation. 15 | - CLI interface to access ARP and Routing tables. 16 | 17 | ## PFM Architecture 18 | 19 | ![Figure showing PFM architecture](./pics/PFM_architecture.png) 20 | 21 | 22 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2010-2014 Intel Corporation 3 | 4 | # binary name 5 | APP = drb_test.exe 6 | 7 | # all source are stored in SRCS-y 8 | 9 | SRCS-y := test.c \ 10 | cuup.c \ 11 | pfm.c \ 12 | pfm_log.c \ 13 | pfm_utils.c \ 14 | tunnel.c \ 15 | drb.c \ 16 | 17 | 18 | 19 | # Build using pkg-config variables if possible 20 | ifeq ($(shell pkg-config --exists libdpdk && echo 0),0) 21 | 22 | all: shared 23 | .PHONY: shared static 24 | shared: build/$(APP)-shared 25 | ln -sf $(APP)-shared build/$(APP) 26 | static: build/$(APP)-static 27 | ln -sf $(APP)-static build/$(APP) 28 | 29 | PKGCONF ?= pkg-config 30 | 31 | PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) 32 | CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) 33 | CFLAGS += -DALLOW_EXPERIMENTAL_API 34 | LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) 35 | LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) 36 | 37 | build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build 38 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 39 | 40 | build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build 41 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) 42 | 43 | build: 44 | @mkdir -p $@ 45 | 46 | .PHONY: clean 47 | clean: 48 | rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared 49 | test -d build && rmdir -p build || true 50 | 51 | else # Build using legacy build system 52 | 53 | ifeq ($(RTE_SDK),) 54 | $(error "Please define RTE_SDK environment variable") 55 | endif 56 | 57 | # Default target, detect a build directory, by looking for a path with a .config 58 | RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) 59 | 60 | include $(RTE_SDK)/mk/rte.vars.mk 61 | 62 | ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),y) 63 | $(error This application can only operate in a linux environment, \ 64 | please change the definition of the RTE_TARGET environment variable) 65 | endif 66 | 67 | CFLAGS += -O3 -g -DTRACE -DCONSLOG 68 | # CFLAGS += -O3 -g -DTRACE 69 | CFLAGS += -DALLOW_EXPERIMENTAL_API 70 | CFLAGS += $(WERROR_FLAGS) 71 | CFLAGS += -lcriterion 72 | 73 | include $(RTE_SDK)/mk/rte.extapp.mk 74 | endif 75 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/cuup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "pfm.h" 8 | #include "pfm_comm.h" 9 | #include "pfm_utils.h" 10 | 11 | #define GTP_PORTNO 2152 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/cuup.h: -------------------------------------------------------------------------------- 1 | #ifndef __CUUP_H__ 2 | #define __CUUP_H__ 1 3 | //XXX test mod 4 | #define MAX_UE_COUNT 10 5 | #define MAX_PDUS_PER_UE 4 // range 1 to 256 6 | #define MAX_DRB_PER_PDUS 4 // range 1 to 32 7 | #define MAX_FLOWS_PER_PDUS 4 // rnage 1 to 32 8 | #define MAX_DRB_PER_UE MAX_DRB_PER_PDUS // range 1 to 32 9 | 10 | 11 | #define MAX_TUNNEL_COUNT (MAX_UE_COUNT * MAX_PDUS_PER_UE * MAX_DRB_PER_UE) 12 | 13 | #define NEW_UL_FLOW_NOTIFY_TIMEOUT 100 // in msec 14 | #define NEW_UL_FLOW_NOTIFY_BUNDLE_SIZE 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/drb.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRB_H__ 2 | #define __DRB_H__ 3 | 4 | 5 | #include "tunnel.h" 6 | #include "ue_ctx.h" 7 | #include "e1ap_comm.h" 8 | #include "e1ap_bearer_modify.h" 9 | #include "cuup.h" 10 | #include "pfm_comm.h" 11 | #include "pfm.h" 12 | #include "cuup.h" 13 | 14 | /********************* 15 | 16 | drb_setup 17 | 18 | Create a new drb entry with given drb_setup_req_info and create it's 19 | drb_setup_succ_rsp_info if required. The entry if created successfully is 20 | assigned to the ue_ctx but not committed.If entry creation failed creation of 21 | failure response must be handled by caller. 22 | 23 | @params 24 | 25 | ue_ctx - pointer to the ue_ctx to populate 26 | req - pointer to the drb_setup_req_info to create drb_entry 27 | succ_rsp - pointer to the drb_setup_succ_rsp_info to populate 28 | if the drb setup was successful 29 | fail_rsp - pointer to the drb_setup_fail_rsp_info to populate in case 30 | drb setup failed 31 | 32 | @returns 33 | 34 | pfm_retval_t - PFM_TRUE - if drb_entry creation was 35 | successful, rsp will be set 36 | 37 | PFM_FALSE - if drb_entry creation was 38 | unsuccessful, rsp will not 39 | be set and fail_rsp must 40 | be set by caller 41 | ***********************/ 42 | pfm_retval_t 43 | drb_setup(ue_ctx_t* ue_ctx, 44 | drb_setup_req_info_t* req, 45 | drb_setup_succ_rsp_info_t* succ_rsp, 46 | drb_setup_fail_rsp_info_t* fail_rsp); 47 | 48 | /********************** 49 | 50 | drb_setup_fail_rsp_create 51 | 52 | Create drb_setup_fail_rsp_info if creation of tunnel entry was unsuccessful 53 | 54 | @params 55 | 56 | req - pointer to drb_setup_req_info that failed drb_create 57 | fail_rsp - pointer to drb_setup_fail_rsp_info that corresponds to 58 | req 59 | cause - The cause for drb_setup failure 60 | 61 | @returns 62 | void 63 | 64 | **********************/ 65 | 66 | void 67 | drb_setup_fail_rsp_create(drb_setup_req_info_t* req, 68 | drb_setup_fail_rsp_info_t *fail_rsp, 69 | e1ap_fail_cause_t cause); 70 | 71 | /************************ 72 | drb_modify 73 | 74 | To modify an existing pdus entry with given drb_setup_req_info and position in 75 | drb_tunnel_list to modify the entry and reassign to list and create it's 76 | responses fail or success depending on result, the drb in the requests are 77 | modified and reassigned but not commited 78 | @params 79 | 80 | ue_ctx - pointer to the ue_ctx to populate 81 | req - pointer to the drb_modify_req_info to create drb_entry 82 | succ_rsp - pointer to the drb_modify_succ_rsp_info to populate 83 | if the drb modification was successful 84 | fail_rsp - pointer to the drb_modify_fail_rsp_info to populate if 85 | the drb modification was unsuccessful 86 | id_x - the index of the entry to be modified in drb_tunnel_list 87 | 88 | @returns 89 | 90 | pfm_retval_t - PFM_TRUE - if drb_entry creation was 91 | successful, rsp will be set 92 | 93 | PFM_FALSE - if drb_entry creation was 94 | unsuccessful, rsp will not 95 | be set and fail_rsp must 96 | be set by caller 97 | **************************/ 98 | 99 | pfm_retval_t 100 | drb_modify(ue_ctx_t* ue_ctx, 101 | drb_modify_req_info_t *req, 102 | drb_setup_succ_rsp_info_t *succ_rsp, 103 | drb_setup_fail_rsp_info_t *fail_rsp, 104 | uint32_t idx); 105 | 106 | 107 | /*************************** 108 | 109 | drb_modify_fail_rsp_create 110 | 111 | create the failure response in case drb_modify fails filling in the required info 112 | into the provided drb_modify_fail_rsp_info pointer 113 | 114 | @params 115 | 116 | req - pointer to the modify request that failed 117 | fail_rsp - pointer to the fail response 118 | cause - reason for failure 119 | 120 | @returns 121 | 122 | void 123 | 124 | ****************************/ 125 | void 126 | drb_modify_fail_rsp_create(drb_modify_req_info_t *req, 127 | drb_setup_fail_rsp_info_t *rsp, 128 | e1ap_fail_cause_t cause); 129 | 130 | pfm_retval_t drb_remove(tunnel_key_t *tunnel_key); 131 | 132 | pfm_retval_t drb_commit(tunnel_t *nt); 133 | 134 | pfm_retval_t drb_rollback(tunnel_t *nt); 135 | #endif 136 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/e1ap_bearer_modify.h: -------------------------------------------------------------------------------- 1 | #ifndef __E1AP_BEARER_MODIFY_H__ 2 | #define __E1AP_BEARER_MODIFY_H__ 1 3 | 4 | #include "cuup.h" 5 | #include "e1ap_comm.h" 6 | 7 | typedef pdus_setup_fail_rsp_info_t pdus_modify_fail_rsp_info_t; 8 | 9 | // BEARER CONTEXT MODIFICATION REQUEST sec 9.2.2.4 of 3GPP TS 38.463 10 | // PDU Session Resource to Modify List 9.3.3.11 11 | // DRB To Modify List 12 | typedef struct 13 | { 14 | uint8_t drb_id; 15 | } drb_modify_req_info_t; 16 | 17 | 18 | // BEARER CONTEXT MODIFICATION REQUEST sec 9.2.2.4 of 3GPP TS 38.463 19 | // PDU Session Resource to Modify List 9.3.3.11 20 | // DRB To Remove List 21 | typedef struct 22 | { 23 | uint8_t drb_id; 24 | } drb_remove_req_info_t; 25 | 26 | // BEARER CONTEXT MODIFICATION REQUEST sec 9.2.2.4 of 3GPP TS 38.463 27 | // PDU Session Resource to Modify List 9.3.3.11 28 | typedef struct 29 | { 30 | uint8_t pdus_id; 31 | 32 | uint8_t drb_setup_count; 33 | uint8_t drb_modify_count; 34 | uint8_t drb_remove_count; 35 | drb_setup_req_info_t drb_setup_list[MAX_DRB_PER_PDUS]; 36 | drb_modify_req_info_t drb_modify_list[MAX_DRB_PER_PDUS]; 37 | drb_remove_req_info_t drb_remove_list[MAX_DRB_PER_PDUS]; 38 | } pdus_modify_req_info_t; 39 | 40 | // BEARER CONTEXT MODIFICATION REQUEST sec 9.2.2.4 of 3GPP TS 38.463 41 | // PDU Session Resource to Remove List 9.3.3.12 42 | typedef struct 43 | { 44 | uint8_t pdus_id; 45 | e1ap_fail_cause_t cause; 46 | } pdus_remove_req_info_t; 47 | 48 | 49 | // BEARER CONTEXT MODIFICATION RESPONSE. sec 9.2.2.5 50 | // PDU Session Resource Modify List 9.3.3.19 51 | typedef struct 52 | { 53 | uint8_t pdus_id; // PDU Session ID 9.3.1.21 54 | uint8_t drb_setup_succ_count; 55 | uint8_t drb_setup_fail_count; 56 | uint8_t drb_modify_succ_count; 57 | uint8_t drb_modify_fail_count; 58 | 59 | // NG DL UP Transport Layer Info 9.3.2.1 60 | // IP Address and TEID of CUUP to which UPF can send DL packets 61 | pfm_ip_addr_t pdus_dl_ip_addr; 62 | uint32_t pdus_dl_teid; 63 | 64 | // DRB Setup List 65 | drb_setup_succ_rsp_info_t drb_setup_succ_list[MAX_DRB_PER_PDUS]; 66 | 67 | // DRB Failed List 68 | drb_setup_fail_rsp_info_t drb_setup_fail_list[MAX_DRB_PER_PDUS]; 69 | 70 | // DRB Modification List 71 | drb_setup_succ_rsp_info_t drb_modify_succ_list[MAX_DRB_PER_PDUS]; 72 | 73 | // DRB Failed To Modify List 74 | drb_setup_fail_rsp_info_t drb_modify_fail_list[MAX_DRB_PER_PDUS]; 75 | 76 | } pdus_modify_succ_rsp_info_t; 77 | 78 | // BEARER CONTEXT MODIFICATION REQUEST sec 9.2.2.4 of 3GPP TS 38.463 79 | typedef struct 80 | { 81 | uint32_t cucp_ue_id; 82 | uint32_t cuup_ue_id; 83 | uint8_t pdus_setup_count; 84 | uint8_t pdus_modify_count; 85 | uint8_t pdus_remove_count; 86 | 87 | // PDU Session Resource to Setup List 9.3.3.10 88 | pdus_setup_req_info_t pdus_setup_list[MAX_PDUS_PER_UE]; 89 | 90 | // PDU Session Resource to Modify List 9.3.3.11 91 | pdus_modify_req_info_t pdus_modify_list[MAX_PDUS_PER_UE]; 92 | 93 | // PDU Session Resource to Remove List 9.3.3.12 94 | pdus_remove_req_info_t pdus_remove_list[MAX_PDUS_PER_UE]; 95 | 96 | } e1ap_bearer_ctx_modify_req_t; 97 | 98 | 99 | // BEARER CONTEXT MODIFICATION RESPONSE. sec 9.2.2.5 of 3GPP TS 38.463 100 | // BEARER CONTEXT MODIFICATION FAILURE sec 9.2.2.6 of 3GPP TS 38.463 101 | typedef struct 102 | { 103 | uint32_t cucp_ue_id; 104 | uint32_t cuup_ue_id; 105 | e1ap_fail_cause_t cause; // set to 0 is success 106 | uint8_t pdus_setup_succ_count; 107 | uint8_t pdus_setup_fail_count; 108 | uint8_t pdus_modify_succ_count; 109 | uint8_t pdus_modify_fail_count; 110 | 111 | // PDU Session Resource Setup List 9.3.3.17 112 | pdus_setup_succ_rsp_info_t pdus_setup_succ_list[MAX_PDUS_PER_UE]; 113 | 114 | // PDU Session Resource Failed List 9.3.3.18 115 | pdus_setup_fail_rsp_info_t pdus_setup_fail_list[MAX_PDUS_PER_UE]; 116 | 117 | // PDU Session Resource Modify List 9.3.3.19 118 | pdus_modify_succ_rsp_info_t pdus_modify_succ_list[MAX_PDUS_PER_UE]; 119 | 120 | // PDU Session Resource Failed To Modify List 9.3.3.20 121 | pdus_modify_fail_rsp_info_t pdus_modify_fail_list[MAX_PDUS_PER_UE]; 122 | 123 | } e1ap_bearer_ctx_modify_rsp_t; 124 | 125 | 126 | pfm_retval_t e1ap_bearer_ctx_modify( 127 | e1ap_bearer_ctx_modify_req_t *req, 128 | e1ap_bearer_ctx_modify_rsp_t *rsp); 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/e1ap_bearer_setup.h: -------------------------------------------------------------------------------- 1 | #ifndef __E1AP_BEARER_SETUP_H__ 2 | #define __E1AP_BEARER_SETUP_H__ 1 3 | 4 | #include "cuup.h" 5 | #include "e1ap_comm.h" 6 | 7 | // BEARER CONTEXT SETUP REQUEST Sec 9.2.2.1 of 3GPP TS 38.463 8 | typedef struct 9 | { 10 | uint32_t cucp_ue_id; 11 | 12 | // PDU Session Resource To Setup List 9.3.3.2 13 | uint8_t pdus_count; 14 | pdus_setup_req_info_t pdus_list[MAX_PDUS_PER_UE]; 15 | } e1ap_bearer_ctx_setup_req_t; 16 | 17 | // BEARER CONTEXT SETUP RESPONSE. sec 9.2.2.2 of 3GPP TS 38.463 18 | typedef struct 19 | { 20 | uint32_t cucp_ue_id; 21 | uint32_t cuup_ue_id; 22 | e1ap_fail_cause_t cause; // set to 0 is sucess 23 | uint8_t pdus_setup_succ_count; 24 | uint8_t pdus_setup_fail_count; 25 | pdus_setup_succ_rsp_info_t pdus_succ_list[MAX_PDUS_PER_UE]; 26 | pdus_setup_fail_rsp_info_t pdus_fail_list[MAX_PDUS_PER_UE]; 27 | } e1ap_bearer_ctx_setup_rsp_t; 28 | 29 | 30 | pfm_retval_t 31 | e1ap_bearer_ctx_setup(e1ap_bearer_ctx_setup_req_t *req,e1ap_bearer_ctx_setup_rsp_t *rsp); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/fixes: -------------------------------------------------------------------------------- 1 | 1. Check for MAX no of drbs per ue in drb_setup 2 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/pfm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "pfm.h" 6 | #include "pfm_comm.h" 7 | 8 | static pfm_bool_t pfm_up = PFM_FALSE; 9 | pfm_retval_t pfm_init(int argc, char *argv[]) 10 | { 11 | int ret; 12 | int lcore_count; 13 | if (pfm_up == PFM_FALSE) 14 | { 15 | ret = rte_eal_init(argc, argv); 16 | if (0 > ret) 17 | { 18 | pfm_log_rte_err(PFM_LOG_EMERG, 19 | "rte_eal_init(argc=%d,argc=%p) failed. Terminating", 20 | argc, argv); 21 | return PFM_FAILED; 22 | } 23 | pfm_trace_msg("EAL Initialized"); 24 | 25 | lcore_count = rte_lcore_count(); 26 | pfm_trace_msg("Detected %d lcores",lcore_count); 27 | pfm_trace_msg("DPPF Initialization successful"); 28 | pfm_up = PFM_TRUE; 29 | } 30 | return PFM_SUCCESS; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/pfm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_H__ 2 | #define __PFM_H__ 1 3 | 4 | #include 5 | #include "pfm_log.h" 6 | 7 | typedef enum 8 | { 9 | PROTOCOL_UDP = 17 10 | } pfm_protocol_t; 11 | 12 | typedef uint32_t pfm_ip_addr_t; 13 | 14 | typedef enum 15 | { 16 | PFM_SUCCESS, 17 | PFM_FAILED, 18 | PFM_NOT_FOUND 19 | } pfm_retval_t; 20 | 21 | typedef enum 22 | { 23 | PFM_FALSE = 0, 24 | PFM_TRUE = 1 25 | } pfm_bool_t; 26 | 27 | pfm_retval_t pfm_init(int argc, char *argv[]); 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/pfm_comm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_COMM_H__ 2 | #define __PFM_COMM_H__ 1 3 | #include 4 | #include "pfm.h" 5 | #define MAX_LCORES 32 6 | #define MAX_LINK_COUNT 5 7 | #define LAST_LINK_ID MAX_LINK_COUNT 8 | #define MAX_KNI_PORTS 5 9 | #define MAX_LOCAL_IP_COUNT (MAX_KNI_PORTS*2) 10 | 11 | #define MBUF_COUNT 4096 12 | #define MBUF_CASHE_SIZE 128 13 | #define MBUF_PRIV_SIZE 0 14 | 15 | /* DPDK object names */ 16 | #define MBUF_NAME "MBUF" 17 | #define TX_RING_NAME "TXRING" 18 | #define RX_RING_NAME "RXRING" 19 | #define DIST_NAME "DISTNAME" 20 | 21 | #define TX_RING_SIZE 64 22 | #define RX_RING_SIZE TX_RING_SIZE 23 | #define TX_BURST_SIZE 32 24 | #define RX_BURST_SIZE TX_BURST_SIZE 25 | 26 | #define MAC_ADDR_SIZE RTE_ETHER_ADDR_LEN 27 | #define IP_ADDR_SIZE 4 28 | #define STR_IP_ADDR_SIZE 20 29 | #define DEFAULT_MTU_SIZE 1500 30 | #define DEFAULT_MIN_MTU_SIZE 68 31 | #define DEFAULT_MAX_MTU_SIZE 65535 32 | 33 | #define TIMER_RESOLUTION_CYCLES 20000000ULL 34 | 35 | #define ARP_TABLE_SIZE 32 36 | 37 | enum { 38 | LCORE_MAIN = 0, 39 | LCORE_RXLOOP = 1, 40 | LCORE_TXLOOP = 2, 41 | LCORE_DISTRIBUTOR = 3, 42 | LCORE_WORKER = 4, 43 | LCORE_MIN_LCORE_COUNT 44 | }; 45 | 46 | #define MAX_WORKERS (MAX_LCORES - LCORE_WORKER) 47 | typedef enum 48 | { 49 | ADMSTATE_UNLOCKED, 50 | ADMSTATE_LOCKED, 51 | } admin_state_t; 52 | 53 | typedef enum 54 | { 55 | OPSSTATE_NOTCONFIGURED, 56 | OPSSTATE_ENABLED, 57 | OPSSTATE_DISABLED, 58 | OPSSTATE_FAULTY 59 | } ops_state_t; 60 | 61 | typedef struct { 62 | int kniIdx; 63 | pfm_ip_addr_t ip_addr; 64 | pfm_ip_addr_t network_mask; 65 | pfm_ip_addr_t default_gateway_ip; 66 | } local_ip_addr_t; 67 | 68 | typedef struct { 69 | int lcore_count; 70 | int kni_count; 71 | int local_ip_count; 72 | local_ip_addr_t local_ip_addr_list[MAX_LOCAL_IP_COUNT]; 73 | struct rte_mempool *mbuf_pool; 74 | struct rte_ring *rx_ring_ptr ; 75 | struct rte_ring *tx_ring_ptr ; 76 | struct rte_kni *kni_ptr; 77 | struct rte_distributor *dist_ptr; 78 | } sys_info_t; 79 | 80 | 81 | extern volatile pfm_bool_t force_quit_g; /* all loops will use this 82 | varable to determin the looping need to continue 83 | or not. By setting this varlbale to TRUE, all loops 84 | can be terminated */ 85 | extern sys_info_t sys_info_g; 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/pfm_utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pfm.h" 7 | #include "pfm_comm.h" 8 | #include "pfm_log.h" 9 | #include "pfm_utils.h" 10 | 11 | pfm_ip_addr_t pfm_str2ip(const char *ip_str) 12 | { 13 | pfm_ip_addr_t ipn; // IP in network order 14 | pfm_ip_addr_t iph; // IP in host order 15 | int ret; 16 | 17 | ret = inet_pton(AF_INET,ip_str,&ipn); 18 | if (1 != ret) 19 | { 20 | pfm_log_std_err(PFM_LOG_WARNING, 21 | "Failed to convert IP=[%s] to " 22 | "pfm_ip_addr_t format", ip_str); 23 | return 0; 24 | } 25 | iph = ntohl(ipn); 26 | return iph; 27 | } 28 | 29 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_str) 30 | { 31 | pfm_ip_addr_t ipn; // IP in network order 32 | 33 | ipn = htonl(iph); 34 | const char *ret = inet_ntop(AF_INET,&ipn,ip_str,STR_IP_ADDR_SIZE); 35 | if (NULL == ret) 36 | { 37 | pfm_log_std_err(PFM_LOG_ERR, 38 | "Failed to IP=[0x%0X] to string format",iph); 39 | return NULL; 40 | } 41 | return ip_str; 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/pfm_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_UTILS_H__ 2 | #define __PFM_UTILS_H__ 1 3 | #include "pfm.h" 4 | 5 | pfm_ip_addr_t pfm_str2ip(const char *ip_str); 6 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_addr_str); 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/run.sh: -------------------------------------------------------------------------------- 1 | sudo ./build/tunnel_test.exe 2 | 3 | 4 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/test_custom.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "pfm.h" 5 | #include "pfm_log.h" 6 | #include "pfm_utils.h" 7 | 8 | #include "cuup.h" 9 | #include "tunnel.h" 10 | #include 11 | #include 12 | 13 | 14 | 15 | TestSuite(tunnel_tests); 16 | 17 | 18 | 19 | Test(tunnel_tests,add_and_commit) 20 | { 21 | pfm_retval_t ret; 22 | tunnel_t *entry1,*entry2; 23 | tunnel_key_t tunnel_key1,tunnel_key2; 24 | int ret_int; 25 | // Test if key alloc is working 26 | printf("value of ENOENT %d\n",ENOENT); 27 | printf("In test 1\n"); 28 | ret = tunnel_key_alloc(0,TUNNEL_TYPE_PDUS,&tunnel_key1); 29 | cr_assert(ret == PFM_SUCCESS,"tunnel key allocation"); 30 | 31 | // Test if tunnel_add works 32 | entry1 = tunnel_add(&tunnel_key1); 33 | cr_assert(entry1 != NULL,"allocate tunnel entry"); 34 | // Storing this key for future use 35 | tunnel_key2 = tunnel_key1; 36 | 37 | // Commit this tunnel 38 | entry1->remote_ip = pfm_str2ip("192.168.77.33"); 39 | entry1->remote_te_id = 5; 40 | ret = tunnel_commit(entry1); 41 | cr_assert(ret == PFM_SUCCESS,"commit the entry"); 42 | 43 | // get back this entry 44 | entry1 = tunnel_get(&tunnel_key1); 45 | cr_assert(entry1 != NULL,"Entry should exist after committing"); 46 | cr_assert((entry1->key.ip_addr == tunnel_key1.ip_addr) && (entry1->key.te_id == tunnel_key1.te_id),"Same entry"); 47 | // try adding another with same key 48 | entry1 = tunnel_add(&tunnel_key1); 49 | cr_assert(entry1 == NULL,"Not allowed to entry with same key when one already exists"); 50 | /*XXX// Fill the table 51 | for (int i = 1;i < MAX_TUNNEL_COUNT;i++) 52 | { 53 | ret = tunnel_key_alloc(0,TUNNEL_TYPE_PDUS,&tunnel_key1); 54 | cr_expect(ret == PFM_SUCCESS,"expect a tunnel key to be allocated"); 55 | 56 | entry1 = tunnel_add(&tunnel_key1); 57 | cr_expect(entry1 != NULL,"Expect a tunnel entry be allocated as long as there is space"); 58 | 59 | ret = tunnel_commit(entry1); 60 | cr_expect(ret == PFM_SUCCESS,"Expect the commit to be succesful"); 61 | } 62 | // When the table is full all should fail 63 | ret = tunnel_key_alloc(0,TUNNEL_TYPE_PDUS,&tunnel_key1); 64 | cr_expect(ret == PFM_FAILED,"expect a tunnel key to be allocated"); 65 | 66 | entry1 = tunnel_add(&tunnel_key1); 67 | cr_expect(entry1 == NULL,"Expect a tunnel entry be allocated as long as there is space"); 68 | 69 | ret = tunnel_commit(entry1); 70 | cr_expect(ret == PFM_FAILED); 71 | XXX*/ 72 | 73 | // You cannot modify tunnels with tunnel get 74 | entry1 = tunnel_get(&tunnel_key2); 75 | entry1->remote_ip = pfm_str2ip("255.255.255.255"); 76 | 77 | // Try modifying tunnels 78 | entry1 = tunnel_modify(&tunnel_key2); 79 | entry1->remote_ip = pfm_str2ip("0.0.0.0"); 80 | ret = tunnel_commit(entry1); 81 | cr_expect(ret == PFM_SUCCESS,"Commit is a success after modification"); 82 | entry1 = tunnel_get(&tunnel_key2); 83 | cr_expect(entry1->remote_ip == pfm_str2ip("0.0.0.0"),"Check if modification is recorded"); 84 | 85 | // Remove a tunnel 86 | ret = tunnel_remove(&tunnel_key2); 87 | cr_assert(ret == PFM_SUCCESS,"The tunnel remove is successful"); 88 | ret = tunnel_commit(entry1); 89 | cr_assert(ret == PFM_SUCCESS,"Committed a removed entry"); 90 | entry1 = tunnel_get(&tunnel_key2); 91 | cr_assert(entry1 == NULL,"Tunnel is removed successfully"); 92 | } 93 | 94 | 95 | 96 | int main(int argc, char *argv[]) { 97 | pfm_retval_t ret; 98 | char *v[0]; 99 | int result = 0; 100 | 101 | v[0] = strdup("/home/arv-sajeev/DPDK/dpdk-19.11/examples/pfm/pfm/criterion_tests/e1ap/comps/tunnel_tests/test.c"); 102 | ret = pfm_init(1,v); 103 | printf("Suite setup complete\n"); 104 | 105 | 106 | cr_assert(ret == PFM_SUCCESS); 107 | 108 | struct criterion_test_set *tests = criterion_initialize(); 109 | 110 | if (criterion_handle_args(argc, argv, true)) 111 | result = !criterion_run_all_tests(tests); 112 | 113 | criterion_finalize(tests); 114 | return result; 115 | } 116 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/tunnel.h: -------------------------------------------------------------------------------- 1 | #ifndef __TUNNEL_H__ 2 | #define __TUNNEL_H__ 1 3 | #include "pfm.h" 4 | #include "cuup.h" 5 | 6 | typedef enum 7 | { 8 | TUNNEL_TYPE_PDUS, 9 | TUNNEL_TYPE_DRB, 10 | } tunnel_type_t; 11 | 12 | typedef struct 13 | { 14 | unsigned int drb_id:5; 15 | unsigned int is_default:1; 16 | unsigned int is_dl_sdap_hdr_enabled:1; 17 | unsigned int is_ul_sdap_hdr_enabled:1; 18 | uint32_t mapped_flow_idx; // valid only if is_ul_sdap_hdr_enabled 19 | uint32_t mapped_pdus_idx; 20 | } drb_info_t; 21 | 22 | typedef struct 23 | { 24 | unsigned int flow_id:6; 25 | unsigned int r_qos_status:2; 26 | uint32_t mapped_drb_idx; 27 | } flow_info_t; 28 | 29 | typedef struct 30 | { 31 | unsigned int pdus_id:8; 32 | unsigned int flow_count:6; 33 | uint64_t ul_new_flow_detected_bit_map; 34 | flow_info_t flow_list[MAX_FLOWS_PER_PDUS]; 35 | } pdus_info_t; 36 | 37 | typedef struct 38 | { 39 | uint32_t ip_addr; 40 | uint32_t te_id; 41 | } tunnel_key_t; 42 | 43 | typedef struct 44 | { 45 | tunnel_key_t key; 46 | pfm_ip_addr_t remote_ip; 47 | uint32_t remote_te_id; 48 | tunnel_type_t tunnel_type:2; 49 | pfm_bool_t is_row_used:1; 50 | union 51 | { 52 | pdus_info_t pdus_info; 53 | drb_info_t drb_info; 54 | }; 55 | } tunnel_t; 56 | 57 | 58 | const tunnel_t* tunnel_get(tunnel_key_t *key); 59 | tunnel_t * tunnel_add(tunnel_key_t *key); 60 | pfm_retval_t tunnel_remove(tunnel_key_t *key); 61 | tunnel_t * tunnel_modify(tunnel_key_t *key); 62 | pfm_retval_t tunnel_commit(tunnel_t* nt); 63 | void tunnel_print_show(FILE *fp, tunnel_key_t *key); 64 | void tunnel_print_list(FILE *fp, tunnel_type_t ttype); 65 | pfm_retval_t tunnel_key_alloc(pfm_ip_addr_t ip,tunnel_type_t ttype,tunnel_key_t *key); 66 | pfm_retval_t tunnel_remove(tunnel_key_t *key); 67 | pfm_retval_t tunnel_rollback(tunnel_t *nt); 68 | #endif 69 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/drb/ue_ctx.h: -------------------------------------------------------------------------------- 1 | #ifndef __UE_CTX_H__ 2 | #define __UE_CTX_H__ 1 3 | 4 | #include "tunnel.h" 5 | 6 | 7 | typedef struct 8 | { 9 | uint32_t cuup_ue_id; // 32 bit gNB-CU-UP UE E1AP ID 10 | uint32_t cucp_ue_id; // 32 bit gNB-CU-CP UE E1AP ID 11 | uint8_t pdus_count:8; // PDU Session count 12 | uint8_t drb_count:5; 13 | uint8_t new_ul_flow_detected_count:5; 14 | pfm_bool_t is_row_used:1; 15 | tunnel_t * pdus_tunnel_list[MAX_PDUS_PER_UE]; 16 | tunnel_t * drb_tunnel_list[MAX_DRB_PER_UE]; 17 | } ue_ctx_t; 18 | 19 | ue_ctx_t * ue_ctx_add(uint32_t ue_id); 20 | pfm_retval_t ue_ctx_remove(uint32_t ue_id); 21 | ue_ctx_t * ue_ctx_modify(uint32_t ue_id); 22 | pfm_retval_t ue_ctx_commit(ue_ctx_t *new_ctx); 23 | const ue_ctx_t * ue_ctx_get(uint32_t ue_id); 24 | void ue_ctx_print_list(FILE *fp); 25 | void ue_ctx_print_show(FILE *fp, uint32_t ue_id); 26 | pfm_retval_t ue_ctx_id_alloc(uint32_t *ue_id); 27 | pfm_retval_t ue_ctx_rollback(ue_ctx_t *ue_ctx); 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2010-2014 Intel Corporation 3 | 4 | # binary name 5 | APP = pdus_test.exe 6 | 7 | # all source are stored in SRCS-y 8 | 9 | SRCS-y := test.c \ 10 | cuup.c \ 11 | pfm.c \ 12 | pfm_log.c \ 13 | pfm_utils.c \ 14 | tunnel.c \ 15 | drb.c \ 16 | pdus.c \ 17 | 18 | 19 | 20 | # Build using pkg-config variables if possible 21 | ifeq ($(shell pkg-config --exists libdpdk && echo 0),0) 22 | 23 | all: shared 24 | .PHONY: shared static 25 | shared: build/$(APP)-shared 26 | ln -sf $(APP)-shared build/$(APP) 27 | static: build/$(APP)-static 28 | ln -sf $(APP)-static build/$(APP) 29 | 30 | PKGCONF ?= pkg-config 31 | 32 | PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) 33 | CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) 34 | CFLAGS += -DALLOW_EXPERIMENTAL_API 35 | LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) 36 | LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) 37 | 38 | build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build 39 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 40 | 41 | build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build 42 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) 43 | 44 | build: 45 | @mkdir -p $@ 46 | 47 | .PHONY: clean 48 | clean: 49 | rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared 50 | test -d build && rmdir -p build || true 51 | 52 | else # Build using legacy build system 53 | 54 | ifeq ($(RTE_SDK),) 55 | $(error "Please define RTE_SDK environment variable") 56 | endif 57 | 58 | # Default target, detect a build directory, by looking for a path with a .config 59 | RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) 60 | 61 | include $(RTE_SDK)/mk/rte.vars.mk 62 | 63 | ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),y) 64 | $(error This application can only operate in a linux environment, \ 65 | please change the definition of the RTE_TARGET environment variable) 66 | endif 67 | 68 | CFLAGS += -O3 -g -DTRACE -DCONSLOG 69 | # CFLAGS += -O3 -g -DTRACE 70 | CFLAGS += -DALLOW_EXPERIMENTAL_API 71 | CFLAGS += $(WERROR_FLAGS) 72 | CFLAGS += -lcriterion 73 | 74 | include $(RTE_SDK)/mk/rte.extapp.mk 75 | endif 76 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/cuup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "pfm.h" 8 | #include "pfm_comm.h" 9 | #include "pfm_utils.h" 10 | 11 | #define GTP_PORTNO 2152 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/cuup.h: -------------------------------------------------------------------------------- 1 | #ifndef __CUUP_H__ 2 | #define __CUUP_H__ 1 3 | //XXX test mod 4 | #define MAX_UE_COUNT 10 5 | #define MAX_PDUS_PER_UE 4 // range 1 to 256 6 | #define MAX_DRB_PER_PDUS 4 // range 1 to 32 7 | #define MAX_FLOWS_PER_PDUS 4 // rnage 1 to 32 8 | #define MAX_DRB_PER_UE MAX_DRB_PER_PDUS // range 1 to 32 9 | 10 | 11 | #define MAX_TUNNEL_COUNT (MAX_UE_COUNT * MAX_PDUS_PER_UE * MAX_DRB_PER_UE) 12 | 13 | #define NEW_UL_FLOW_NOTIFY_TIMEOUT 100 // in msec 14 | #define NEW_UL_FLOW_NOTIFY_BUNDLE_SIZE 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/drb.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRB_H__ 2 | #define __DRB_H__ 3 | 4 | 5 | #include "tunnel.h" 6 | #include "ue_ctx.h" 7 | #include "e1ap_comm.h" 8 | #include "e1ap_bearer_modify.h" 9 | #include "cuup.h" 10 | #include "pfm_comm.h" 11 | #include "pfm.h" 12 | #include "cuup.h" 13 | 14 | /********************* 15 | 16 | drb_setup 17 | 18 | Create a new drb entry with given drb_setup_req_info and create it's 19 | drb_setup_succ_rsp_info if required. The entry if created successfully is 20 | assigned to the ue_ctx but not committed.If entry creation failed creation of 21 | failure response must be handled by caller. 22 | 23 | @params 24 | 25 | ue_ctx - pointer to the ue_ctx to populate 26 | req - pointer to the drb_setup_req_info to create drb_entry 27 | succ_rsp - pointer to the drb_setup_succ_rsp_info to populate 28 | if the drb setup was successful 29 | fail_rsp - pointer to the drb_setup_fail_rsp_info to populate in case 30 | drb setup failed 31 | 32 | @returns 33 | 34 | pfm_retval_t - PFM_TRUE - if drb_entry creation was 35 | successful, rsp will be set 36 | 37 | PFM_FALSE - if drb_entry creation was 38 | unsuccessful, rsp will not 39 | be set and fail_rsp must 40 | be set by caller 41 | ***********************/ 42 | pfm_retval_t 43 | drb_setup(ue_ctx_t* ue_ctx, 44 | drb_setup_req_info_t* req, 45 | drb_setup_succ_rsp_info_t* succ_rsp, 46 | drb_setup_fail_rsp_info_t* fail_rsp); 47 | 48 | /********************** 49 | 50 | drb_setup_fail_rsp_create 51 | 52 | Create drb_setup_fail_rsp_info if creation of tunnel entry was unsuccessful 53 | 54 | @params 55 | 56 | req - pointer to drb_setup_req_info that failed drb_create 57 | fail_rsp - pointer to drb_setup_fail_rsp_info that corresponds to 58 | req 59 | cause - The cause for drb_setup failure 60 | 61 | @returns 62 | void 63 | 64 | **********************/ 65 | 66 | void 67 | drb_setup_fail_rsp_create(drb_setup_req_info_t* req, 68 | drb_setup_fail_rsp_info_t *fail_rsp, 69 | e1ap_fail_cause_t cause); 70 | 71 | /************************ 72 | drb_modify 73 | 74 | To modify an existing pdus entry with given drb_setup_req_info and position in 75 | drb_tunnel_list to modify the entry and reassign to list and create it's 76 | responses fail or success depending on result, the drb in the requests are 77 | modified and reassigned but not commited 78 | @params 79 | 80 | ue_ctx - pointer to the ue_ctx to populate 81 | req - pointer to the drb_modify_req_info to create drb_entry 82 | succ_rsp - pointer to the drb_modify_succ_rsp_info to populate 83 | if the drb modification was successful 84 | fail_rsp - pointer to the drb_modify_fail_rsp_info to populate if 85 | the drb modification was unsuccessful 86 | id_x - the index of the entry to be modified in drb_tunnel_list 87 | 88 | @returns 89 | 90 | pfm_retval_t - PFM_TRUE - if drb_entry creation was 91 | successful, rsp will be set 92 | 93 | PFM_FALSE - if drb_entry creation was 94 | unsuccessful, rsp will not 95 | be set and fail_rsp must 96 | be set by caller 97 | **************************/ 98 | 99 | pfm_retval_t 100 | drb_modify(ue_ctx_t* ue_ctx, 101 | drb_modify_req_info_t *req, 102 | drb_setup_succ_rsp_info_t *succ_rsp, 103 | drb_setup_fail_rsp_info_t *fail_rsp, 104 | uint32_t idx); 105 | 106 | 107 | /*************************** 108 | 109 | drb_modify_fail_rsp_create 110 | 111 | create the failure response in case drb_modify fails filling in the required info 112 | into the provided drb_modify_fail_rsp_info pointer 113 | 114 | @params 115 | 116 | req - pointer to the modify request that failed 117 | fail_rsp - pointer to the fail response 118 | cause - reason for failure 119 | 120 | @returns 121 | 122 | void 123 | 124 | ****************************/ 125 | void 126 | drb_modify_fail_rsp_create(drb_modify_req_info_t *req, 127 | drb_setup_fail_rsp_info_t *rsp, 128 | e1ap_fail_cause_t cause); 129 | 130 | pfm_retval_t drb_remove(tunnel_key_t *tunnel_key); 131 | 132 | pfm_retval_t drb_commit(tunnel_t *nt); 133 | 134 | pfm_retval_t drb_rollback(tunnel_t *nt); 135 | #endif 136 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/e1ap_bearer_setup.h: -------------------------------------------------------------------------------- 1 | #ifndef __E1AP_BEARER_SETUP_H__ 2 | #define __E1AP_BEARER_SETUP_H__ 1 3 | 4 | #include "cuup.h" 5 | #include "e1ap_comm.h" 6 | 7 | // BEARER CONTEXT SETUP REQUEST Sec 9.2.2.1 of 3GPP TS 38.463 8 | typedef struct 9 | { 10 | uint32_t cucp_ue_id; 11 | 12 | // PDU Session Resource To Setup List 9.3.3.2 13 | uint8_t pdus_count; 14 | pdus_setup_req_info_t pdus_list[MAX_PDUS_PER_UE]; 15 | } e1ap_bearer_ctx_setup_req_t; 16 | 17 | // BEARER CONTEXT SETUP RESPONSE. sec 9.2.2.2 of 3GPP TS 38.463 18 | typedef struct 19 | { 20 | uint32_t cucp_ue_id; 21 | uint32_t cuup_ue_id; 22 | e1ap_fail_cause_t cause; // set to 0 is sucess 23 | uint8_t pdus_setup_succ_count; 24 | uint8_t pdus_setup_fail_count; 25 | pdus_setup_succ_rsp_info_t pdus_succ_list[MAX_PDUS_PER_UE]; 26 | pdus_setup_fail_rsp_info_t pdus_fail_list[MAX_PDUS_PER_UE]; 27 | } e1ap_bearer_ctx_setup_rsp_t; 28 | 29 | 30 | pfm_retval_t 31 | e1ap_bearer_ctx_setup(e1ap_bearer_ctx_setup_req_t *req,e1ap_bearer_ctx_setup_rsp_t *rsp); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/fixes: -------------------------------------------------------------------------------- 1 | 1. Check for MAX no of drbs per ue in drb_setup 2 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/pfm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "pfm.h" 6 | #include "pfm_comm.h" 7 | 8 | static pfm_bool_t pfm_up = PFM_FALSE; 9 | pfm_retval_t pfm_init(int argc, char *argv[]) 10 | { 11 | int ret; 12 | int lcore_count; 13 | if (pfm_up == PFM_FALSE) 14 | { 15 | ret = rte_eal_init(argc, argv); 16 | if (0 > ret) 17 | { 18 | pfm_log_rte_err(PFM_LOG_EMERG, 19 | "rte_eal_init(argc=%d,argc=%p) failed. Terminating", 20 | argc, argv); 21 | return PFM_FAILED; 22 | } 23 | pfm_trace_msg("EAL Initialized"); 24 | 25 | lcore_count = rte_lcore_count(); 26 | pfm_trace_msg("Detected %d lcores",lcore_count); 27 | pfm_trace_msg("DPPF Initialization successful"); 28 | pfm_up = PFM_TRUE; 29 | } 30 | return PFM_SUCCESS; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/pfm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_H__ 2 | #define __PFM_H__ 1 3 | 4 | #include 5 | #include "pfm_log.h" 6 | 7 | typedef enum 8 | { 9 | PROTOCOL_UDP = 17 10 | } pfm_protocol_t; 11 | 12 | typedef uint32_t pfm_ip_addr_t; 13 | 14 | typedef enum 15 | { 16 | PFM_SUCCESS, 17 | PFM_FAILED, 18 | PFM_NOT_FOUND 19 | } pfm_retval_t; 20 | 21 | typedef enum 22 | { 23 | PFM_FALSE = 0, 24 | PFM_TRUE = 1 25 | } pfm_bool_t; 26 | 27 | pfm_retval_t pfm_init(int argc, char *argv[]); 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/pfm_comm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_COMM_H__ 2 | #define __PFM_COMM_H__ 1 3 | #include 4 | #include "pfm.h" 5 | #define MAX_LCORES 32 6 | #define MAX_LINK_COUNT 5 7 | #define LAST_LINK_ID MAX_LINK_COUNT 8 | #define MAX_KNI_PORTS 5 9 | #define MAX_LOCAL_IP_COUNT (MAX_KNI_PORTS*2) 10 | 11 | #define MBUF_COUNT 4096 12 | #define MBUF_CASHE_SIZE 128 13 | #define MBUF_PRIV_SIZE 0 14 | 15 | /* DPDK object names */ 16 | #define MBUF_NAME "MBUF" 17 | #define TX_RING_NAME "TXRING" 18 | #define RX_RING_NAME "RXRING" 19 | #define DIST_NAME "DISTNAME" 20 | 21 | #define TX_RING_SIZE 64 22 | #define RX_RING_SIZE TX_RING_SIZE 23 | #define TX_BURST_SIZE 32 24 | #define RX_BURST_SIZE TX_BURST_SIZE 25 | 26 | #define MAC_ADDR_SIZE RTE_ETHER_ADDR_LEN 27 | #define IP_ADDR_SIZE 4 28 | #define STR_IP_ADDR_SIZE 20 29 | #define DEFAULT_MTU_SIZE 1500 30 | #define DEFAULT_MIN_MTU_SIZE 68 31 | #define DEFAULT_MAX_MTU_SIZE 65535 32 | 33 | #define TIMER_RESOLUTION_CYCLES 20000000ULL 34 | 35 | #define ARP_TABLE_SIZE 32 36 | 37 | enum { 38 | LCORE_MAIN = 0, 39 | LCORE_RXLOOP = 1, 40 | LCORE_TXLOOP = 2, 41 | LCORE_DISTRIBUTOR = 3, 42 | LCORE_WORKER = 4, 43 | LCORE_MIN_LCORE_COUNT 44 | }; 45 | 46 | #define MAX_WORKERS (MAX_LCORES - LCORE_WORKER) 47 | typedef enum 48 | { 49 | ADMSTATE_UNLOCKED, 50 | ADMSTATE_LOCKED, 51 | } admin_state_t; 52 | 53 | typedef enum 54 | { 55 | OPSSTATE_NOTCONFIGURED, 56 | OPSSTATE_ENABLED, 57 | OPSSTATE_DISABLED, 58 | OPSSTATE_FAULTY 59 | } ops_state_t; 60 | 61 | typedef struct { 62 | int kniIdx; 63 | pfm_ip_addr_t ip_addr; 64 | pfm_ip_addr_t network_mask; 65 | pfm_ip_addr_t default_gateway_ip; 66 | } local_ip_addr_t; 67 | 68 | typedef struct { 69 | int lcore_count; 70 | int kni_count; 71 | int local_ip_count; 72 | local_ip_addr_t local_ip_addr_list[MAX_LOCAL_IP_COUNT]; 73 | struct rte_mempool *mbuf_pool; 74 | struct rte_ring *rx_ring_ptr ; 75 | struct rte_ring *tx_ring_ptr ; 76 | struct rte_kni *kni_ptr; 77 | struct rte_distributor *dist_ptr; 78 | } sys_info_t; 79 | 80 | 81 | extern volatile pfm_bool_t force_quit_g; /* all loops will use this 82 | varable to determin the looping need to continue 83 | or not. By setting this varlbale to TRUE, all loops 84 | can be terminated */ 85 | extern sys_info_t sys_info_g; 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/pfm_utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pfm.h" 7 | #include "pfm_comm.h" 8 | #include "pfm_log.h" 9 | #include "pfm_utils.h" 10 | 11 | pfm_ip_addr_t pfm_str2ip(const char *ip_str) 12 | { 13 | pfm_ip_addr_t ipn; // IP in network order 14 | pfm_ip_addr_t iph; // IP in host order 15 | int ret; 16 | 17 | ret = inet_pton(AF_INET,ip_str,&ipn); 18 | if (1 != ret) 19 | { 20 | pfm_log_std_err(PFM_LOG_WARNING, 21 | "Failed to convert IP=[%s] to " 22 | "pfm_ip_addr_t format", ip_str); 23 | return 0; 24 | } 25 | iph = ntohl(ipn); 26 | return iph; 27 | } 28 | 29 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_str) 30 | { 31 | pfm_ip_addr_t ipn; // IP in network order 32 | 33 | ipn = htonl(iph); 34 | const char *ret = inet_ntop(AF_INET,&ipn,ip_str,STR_IP_ADDR_SIZE); 35 | if (NULL == ret) 36 | { 37 | pfm_log_std_err(PFM_LOG_ERR, 38 | "Failed to IP=[0x%0X] to string format",iph); 39 | return NULL; 40 | } 41 | return ip_str; 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/pfm_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_UTILS_H__ 2 | #define __PFM_UTILS_H__ 1 3 | #include "pfm.h" 4 | 5 | pfm_ip_addr_t pfm_str2ip(const char *ip_str); 6 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_addr_str); 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/run.sh: -------------------------------------------------------------------------------- 1 | sudo ./build/tunnel_test.exe 2 | 3 | 4 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include "pfm.h" 7 | #include "pfm_log.h" 8 | #include "pfm_utils.h" 9 | 10 | #include "cuup.h" 11 | #include "tunnel.h" 12 | #include "ue_ctx.h" 13 | #include "drb.h" 14 | #include "pdus.h" 15 | #include 16 | #include 17 | #include "e1ap_comm.h" 18 | #include "e1ap_bearer_setup.h" 19 | #include "e1ap_bearer_modify.h" 20 | 21 | void setup() 22 | { 23 | printf("In test suite setup\n"); 24 | pfm_retval_t ret; 25 | char *v[0]; 26 | v[0] = strdup("/home/arv-sajeev/DPDK/dpdk-19.11/examples/pfm/criterion_tests/e1ap/pdus/build/pdus_test.exe"); 27 | ret = pfm_init(1,v); 28 | cr_assert(ret == PFM_SUCCESS); 29 | printf("Suite setup complete\n"); 30 | } 31 | 32 | void cleanup() 33 | { 34 | int ret; 35 | printf("In test suite cleanup\n"); 36 | ret = rte_eal_cleanup(); 37 | cr_assert(ret == 0,"Test suite cleanup complete\n"); 38 | } 39 | 40 | TestSuite(setup_suite,.init = setup,.fini = cleanup,.description = 41 | "\nChecks for \n\t1. Successful pdus_setup\n\t2.Appropriate succ and fail rsp\n"); 42 | 43 | Test(setup_suite,test1,.description = 44 | "\nChecks for \n\t1. complete successful setup\n\t2. Appropriate succ rsp\n\t3. Failure to add duplicate") 45 | { 46 | pfm_retval_t ret_val; 47 | int i,ret; 48 | ue_ctx_t ue_ctx; 49 | pdus_setup_req_info_t req; 50 | pdus_setup_succ_rsp_info_t succ_rsp; 51 | pdus_setup_fail_rsp_info_t fail_rsp; 52 | 53 | 54 | // Setting up ue_ctx 55 | ue_ctx.cuup_ue_id = 4; 56 | ue_ctx.cucp_ue_id = 5; 57 | ue_ctx.pdus_count = 0; 58 | ue_ctx.drb_count = 0; 59 | 60 | // Setting up pdus req 61 | req.pdus_id = 3; 62 | req.drb_count = 2; 63 | req.pdus_ul_ip_addr = pfm_str2ip("192.168.0.1"); 64 | req.pdus_ul_teid = 3; 65 | 66 | // Setting up drb req 67 | req.drb_list[0].drb_id = 1; 68 | req.drb_list[0].drb_dl_ip_addr = pfm_str2ip("192.168.0.1"); 69 | req.drb_list[0].drb_dl_teid = 0; 70 | 71 | req.drb_list[1].drb_id = 2; 72 | req.drb_list[1].drb_dl_ip_addr = pfm_str2ip("192.168.0.2"); 73 | req.drb_list[1].drb_dl_teid = 1; 74 | 75 | // pdus setup 76 | ret_val = pdus_setup(&ue_ctx,&req,&succ_rsp,&fail_rsp); 77 | cr_assert(ret_val == PFM_SUCCESS,"successful setup"); 78 | cr_assert(succ_rsp.pdus_id == req.pdus_id && succ_rsp.drb_setup_succ_count == req.drb_count, 79 | "Appropriate succ rsp"); 80 | } 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/tunnel.h: -------------------------------------------------------------------------------- 1 | #ifndef __TUNNEL_H__ 2 | #define __TUNNEL_H__ 1 3 | #include "pfm.h" 4 | #include "cuup.h" 5 | 6 | typedef enum 7 | { 8 | TUNNEL_TYPE_PDUS, 9 | TUNNEL_TYPE_DRB, 10 | } tunnel_type_t; 11 | 12 | typedef struct 13 | { 14 | unsigned int drb_id:5; 15 | unsigned int is_default:1; 16 | unsigned int is_dl_sdap_hdr_enabled:1; 17 | unsigned int is_ul_sdap_hdr_enabled:1; 18 | uint32_t mapped_flow_idx; // valid only if is_ul_sdap_hdr_enabled 19 | uint32_t mapped_pdus_idx; 20 | } drb_info_t; 21 | 22 | typedef struct 23 | { 24 | unsigned int flow_id:6; 25 | unsigned int r_qos_status:2; 26 | uint32_t mapped_drb_idx; 27 | } flow_info_t; 28 | 29 | typedef struct 30 | { 31 | unsigned int pdus_id:8; 32 | unsigned int flow_count:6; 33 | uint64_t ul_new_flow_detected_bit_map; 34 | flow_info_t flow_list[MAX_FLOWS_PER_PDUS]; 35 | } pdus_info_t; 36 | 37 | typedef struct 38 | { 39 | uint32_t ip_addr; 40 | uint32_t te_id; 41 | } tunnel_key_t; 42 | 43 | typedef struct 44 | { 45 | tunnel_key_t key; 46 | pfm_ip_addr_t remote_ip; 47 | uint32_t remote_te_id; 48 | tunnel_type_t tunnel_type:2; 49 | pfm_bool_t is_row_used:1; 50 | union 51 | { 52 | pdus_info_t pdus_info; 53 | drb_info_t drb_info; 54 | }; 55 | } tunnel_t; 56 | 57 | 58 | const tunnel_t* tunnel_get(tunnel_key_t *key); 59 | tunnel_t * tunnel_add(tunnel_key_t *key); 60 | pfm_retval_t tunnel_remove(tunnel_key_t *key); 61 | tunnel_t * tunnel_modify(tunnel_key_t *key); 62 | pfm_retval_t tunnel_commit(tunnel_t* nt); 63 | void tunnel_print_show(FILE *fp, tunnel_key_t *key); 64 | void tunnel_print_list(FILE *fp, tunnel_type_t ttype); 65 | pfm_retval_t tunnel_key_alloc(pfm_ip_addr_t ip,tunnel_type_t ttype,tunnel_key_t *key); 66 | pfm_retval_t tunnel_remove(tunnel_key_t *key); 67 | pfm_retval_t tunnel_rollback(tunnel_t *nt); 68 | #endif 69 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/pdus/ue_ctx.h: -------------------------------------------------------------------------------- 1 | #ifndef __UE_CTX_H__ 2 | #define __UE_CTX_H__ 1 3 | 4 | #include "tunnel.h" 5 | 6 | 7 | typedef struct 8 | { 9 | uint32_t cuup_ue_id; // 32 bit gNB-CU-UP UE E1AP ID 10 | uint32_t cucp_ue_id; // 32 bit gNB-CU-CP UE E1AP ID 11 | uint8_t pdus_count:8; // PDU Session count 12 | uint8_t drb_count:5; 13 | uint8_t new_ul_flow_detected_count:5; 14 | pfm_bool_t is_row_used:1; 15 | tunnel_t * pdus_tunnel_list[MAX_PDUS_PER_UE]; 16 | tunnel_t * drb_tunnel_list[MAX_DRB_PER_UE]; 17 | } ue_ctx_t; 18 | 19 | ue_ctx_t * ue_ctx_add(uint32_t ue_id); 20 | pfm_retval_t ue_ctx_remove(uint32_t ue_id); 21 | ue_ctx_t * ue_ctx_modify(uint32_t ue_id); 22 | pfm_retval_t ue_ctx_commit(ue_ctx_t *new_ctx); 23 | const ue_ctx_t * ue_ctx_get(uint32_t ue_id); 24 | void ue_ctx_print_list(FILE *fp); 25 | void ue_ctx_print_show(FILE *fp, uint32_t ue_id); 26 | pfm_retval_t ue_ctx_id_alloc(uint32_t *ue_id); 27 | pfm_retval_t ue_ctx_rollback(ue_ctx_t *ue_ctx); 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2010-2014 Intel Corporation 3 | 4 | # binary name 5 | APP = tunnel_test.exe 6 | 7 | # all source are stored in SRCS-y 8 | 9 | SRCS-y := test.c \ 10 | cuup.c \ 11 | pfm.c \ 12 | pfm_log.c \ 13 | pfm_utils.c \ 14 | tunnel.c \ 15 | 16 | 17 | # Build using pkg-config variables if possible 18 | ifeq ($(shell pkg-config --exists libdpdk && echo 0),0) 19 | 20 | all: shared 21 | .PHONY: shared static 22 | shared: build/$(APP)-shared 23 | ln -sf $(APP)-shared build/$(APP) 24 | static: build/$(APP)-static 25 | ln -sf $(APP)-static build/$(APP) 26 | 27 | PKGCONF ?= pkg-config 28 | 29 | PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) 30 | CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) 31 | CFLAGS += -DALLOW_EXPERIMENTAL_API 32 | LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) 33 | LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) 34 | 35 | build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build 36 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 37 | 38 | build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build 39 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) 40 | 41 | build: 42 | @mkdir -p $@ 43 | 44 | .PHONY: clean 45 | clean: 46 | rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared 47 | test -d build && rmdir -p build || true 48 | 49 | else # Build using legacy build system 50 | 51 | ifeq ($(RTE_SDK),) 52 | $(error "Please define RTE_SDK environment variable") 53 | endif 54 | 55 | # Default target, detect a build directory, by looking for a path with a .config 56 | RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) 57 | 58 | include $(RTE_SDK)/mk/rte.vars.mk 59 | 60 | ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),y) 61 | $(error This application can only operate in a linux environment, \ 62 | please change the definition of the RTE_TARGET environment variable) 63 | endif 64 | 65 | CFLAGS += -O3 -g -DTRACE -DCONSLOG 66 | # CFLAGS += -O3 -g -DTRACE 67 | CFLAGS += -DALLOW_EXPERIMENTAL_API 68 | CFLAGS += $(WERROR_FLAGS) 69 | CFLAGS += -lcriterion 70 | 71 | include $(RTE_SDK)/mk/rte.extapp.mk 72 | endif 73 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/cuup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "pfm.h" 8 | #include "pfm_comm.h" 9 | #include "pfm_utils.h" 10 | 11 | #define GTP_PORTNO 2152 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/cuup.h: -------------------------------------------------------------------------------- 1 | #ifndef __CUUP_H__ 2 | #define __CUUP_H__ 1 3 | //XXX TEST MOD 4 | #define MAX_UE_COUNT 10 5 | #define MAX_PDUS_PER_UE 4 // range 1 to 256 6 | #define MAX_DRB_PER_PDUS 4 // range 1 to 32 7 | #define MAX_FLOWS_PER_PDUS 4 // rnage 1 to 32 8 | #define MAX_DRB_PER_UE MAX_DRB_PER_PDUS // range 1 to 32 9 | 10 | 11 | #define MAX_TUNNEL_COUNT (MAX_UE_COUNT * MAX_PDUS_PER_UE * MAX_DRB_PER_UE) 12 | 13 | #define NEW_UL_FLOW_NOTIFY_TIMEOUT 100 // in msec 14 | #define NEW_UL_FLOW_NOTIFY_BUNDLE_SIZE 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/fixes: -------------------------------------------------------------------------------- 1 | 1. Change lookup check value to >= than = 2 | 2. Tunnel get if condition needs brackets 3 | 3. Change tunnel_hash_table key size 4 | 4. Fixes in tunnel id freeing and generation 5 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/pfm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "pfm.h" 6 | #include "pfm_comm.h" 7 | 8 | static pfm_bool_t pfm_up = PFM_FALSE; 9 | pfm_retval_t pfm_init(int argc, char *argv[]) 10 | { 11 | int ret; 12 | int lcore_count; 13 | if (pfm_up == PFM_FALSE) 14 | { 15 | ret = rte_eal_init(argc, argv); 16 | if (0 > ret) 17 | { 18 | pfm_log_rte_err(PFM_LOG_EMERG, 19 | "rte_eal_init(argc=%d,argc=%p) failed. Terminating", 20 | argc, argv); 21 | return PFM_FAILED; 22 | } 23 | pfm_trace_msg("EAL Initialized"); 24 | 25 | lcore_count = rte_lcore_count(); 26 | pfm_trace_msg("Detected %d lcores",lcore_count); 27 | pfm_trace_msg("DPPF Initialization successful"); 28 | pfm_up = PFM_TRUE; 29 | } 30 | return PFM_SUCCESS; 31 | } 32 | 33 | 34 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/pfm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_H__ 2 | #define __PFM_H__ 1 3 | 4 | #include 5 | #include "pfm_log.h" 6 | 7 | typedef enum 8 | { 9 | PROTOCOL_UDP = 17 10 | } pfm_protocol_t; 11 | 12 | typedef uint32_t pfm_ip_addr_t; 13 | 14 | typedef enum 15 | { 16 | PFM_SUCCESS, 17 | PFM_FAILED, 18 | PFM_NOT_FOUND 19 | } pfm_retval_t; 20 | 21 | typedef enum 22 | { 23 | PFM_FALSE = 0, 24 | PFM_TRUE = 1 25 | } pfm_bool_t; 26 | 27 | pfm_retval_t pfm_init(int argc, char *argv[]); 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/pfm_comm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_COMM_H__ 2 | #define __PFM_COMM_H__ 1 3 | #include 4 | #include "pfm.h" 5 | #define MAX_LCORES 32 6 | #define MAX_LINK_COUNT 5 7 | #define LAST_LINK_ID MAX_LINK_COUNT 8 | #define MAX_KNI_PORTS 5 9 | #define MAX_LOCAL_IP_COUNT (MAX_KNI_PORTS*2) 10 | 11 | #define MBUF_COUNT 4096 12 | #define MBUF_CASHE_SIZE 128 13 | #define MBUF_PRIV_SIZE 0 14 | 15 | /* DPDK object names */ 16 | #define MBUF_NAME "MBUF" 17 | #define TX_RING_NAME "TXRING" 18 | #define RX_RING_NAME "RXRING" 19 | #define DIST_NAME "DISTNAME" 20 | 21 | #define TX_RING_SIZE 64 22 | #define RX_RING_SIZE TX_RING_SIZE 23 | #define TX_BURST_SIZE 32 24 | #define RX_BURST_SIZE TX_BURST_SIZE 25 | 26 | #define MAC_ADDR_SIZE RTE_ETHER_ADDR_LEN 27 | #define IP_ADDR_SIZE 4 28 | #define STR_IP_ADDR_SIZE 20 29 | #define DEFAULT_MTU_SIZE 1500 30 | #define DEFAULT_MIN_MTU_SIZE 68 31 | #define DEFAULT_MAX_MTU_SIZE 65535 32 | 33 | #define TIMER_RESOLUTION_CYCLES 20000000ULL 34 | 35 | #define ARP_TABLE_SIZE 32 36 | 37 | enum { 38 | LCORE_MAIN = 0, 39 | LCORE_RXLOOP = 1, 40 | LCORE_TXLOOP = 2, 41 | LCORE_DISTRIBUTOR = 3, 42 | LCORE_WORKER = 4, 43 | LCORE_MIN_LCORE_COUNT 44 | }; 45 | 46 | #define MAX_WORKERS (MAX_LCORES - LCORE_WORKER) 47 | typedef enum 48 | { 49 | ADMSTATE_UNLOCKED, 50 | ADMSTATE_LOCKED, 51 | } admin_state_t; 52 | 53 | typedef enum 54 | { 55 | OPSSTATE_NOTCONFIGURED, 56 | OPSSTATE_ENABLED, 57 | OPSSTATE_DISABLED, 58 | OPSSTATE_FAULTY 59 | } ops_state_t; 60 | 61 | typedef struct { 62 | int kniIdx; 63 | pfm_ip_addr_t ip_addr; 64 | pfm_ip_addr_t network_mask; 65 | pfm_ip_addr_t default_gateway_ip; 66 | } local_ip_addr_t; 67 | 68 | typedef struct { 69 | int lcore_count; 70 | int kni_count; 71 | int local_ip_count; 72 | local_ip_addr_t local_ip_addr_list[MAX_LOCAL_IP_COUNT]; 73 | struct rte_mempool *mbuf_pool; 74 | struct rte_ring *rx_ring_ptr ; 75 | struct rte_ring *tx_ring_ptr ; 76 | struct rte_kni *kni_ptr; 77 | struct rte_distributor *dist_ptr; 78 | } sys_info_t; 79 | 80 | 81 | extern volatile pfm_bool_t force_quit_g; /* all loops will use this 82 | varable to determin the looping need to continue 83 | or not. By setting this varlbale to TRUE, all loops 84 | can be terminated */ 85 | extern sys_info_t sys_info_g; 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/pfm_utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pfm.h" 7 | #include "pfm_comm.h" 8 | #include "pfm_log.h" 9 | #include "pfm_utils.h" 10 | 11 | pfm_ip_addr_t pfm_str2ip(const char *ip_str) 12 | { 13 | pfm_ip_addr_t ipn; // IP in network order 14 | pfm_ip_addr_t iph; // IP in host order 15 | int ret; 16 | 17 | ret = inet_pton(AF_INET,ip_str,&ipn); 18 | if (1 != ret) 19 | { 20 | pfm_log_std_err(PFM_LOG_WARNING, 21 | "Failed to convert IP=[%s] to " 22 | "pfm_ip_addr_t format", ip_str); 23 | return 0; 24 | } 25 | iph = ntohl(ipn); 26 | return iph; 27 | } 28 | 29 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_str) 30 | { 31 | pfm_ip_addr_t ipn; // IP in network order 32 | 33 | ipn = htonl(iph); 34 | const char *ret = inet_ntop(AF_INET,&ipn,ip_str,STR_IP_ADDR_SIZE); 35 | if (NULL == ret) 36 | { 37 | pfm_log_std_err(PFM_LOG_ERR, 38 | "Failed to IP=[0x%0X] to string format",iph); 39 | return NULL; 40 | } 41 | return ip_str; 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/pfm_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_UTILS_H__ 2 | #define __PFM_UTILS_H__ 1 3 | #include "pfm.h" 4 | 5 | pfm_ip_addr_t pfm_str2ip(const char *ip_str); 6 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_addr_str); 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/run.sh: -------------------------------------------------------------------------------- 1 | sudo ./build/tunnel_test.exe 2 | 3 | 4 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/test_custom.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "pfm.h" 5 | #include "pfm_log.h" 6 | #include "pfm_utils.h" 7 | 8 | #include "cuup.h" 9 | #include "tunnel.h" 10 | #include 11 | #include 12 | 13 | 14 | 15 | TestSuite(tunnel_tests); 16 | 17 | 18 | 19 | Test(tunnel_tests,add_and_commit) 20 | { 21 | pfm_retval_t ret; 22 | tunnel_t *entry1,*entry2; 23 | tunnel_key_t tunnel_key1,tunnel_key2; 24 | int ret_int; 25 | // Test if key alloc is working 26 | printf("value of ENOENT %d\n",ENOENT); 27 | printf("In test 1\n"); 28 | ret = tunnel_key_alloc(0,TUNNEL_TYPE_PDUS,&tunnel_key1); 29 | cr_assert(ret == PFM_SUCCESS,"tunnel key allocation"); 30 | 31 | // Test if tunnel_add works 32 | entry1 = tunnel_add(&tunnel_key1); 33 | cr_assert(entry1 != NULL,"allocate tunnel entry"); 34 | // Storing this key for future use 35 | tunnel_key2 = tunnel_key1; 36 | 37 | // Commit this tunnel 38 | entry1->remote_ip = pfm_str2ip("192.168.77.33"); 39 | entry1->remote_te_id = 5; 40 | ret = tunnel_commit(entry1); 41 | cr_assert(ret == PFM_SUCCESS,"commit the entry"); 42 | 43 | // get back this entry 44 | entry1 = tunnel_get(&tunnel_key1); 45 | cr_assert(entry1 != NULL,"Entry should exist after committing"); 46 | cr_assert((entry1->key.ip_addr == tunnel_key1.ip_addr) && (entry1->key.te_id == tunnel_key1.te_id),"Same entry"); 47 | // try adding another with same key 48 | entry1 = tunnel_add(&tunnel_key1); 49 | cr_assert(entry1 == NULL,"Not allowed to entry with same key when one already exists"); 50 | /*XXX// Fill the table 51 | for (int i = 1;i < MAX_TUNNEL_COUNT;i++) 52 | { 53 | ret = tunnel_key_alloc(0,TUNNEL_TYPE_PDUS,&tunnel_key1); 54 | cr_expect(ret == PFM_SUCCESS,"expect a tunnel key to be allocated"); 55 | 56 | entry1 = tunnel_add(&tunnel_key1); 57 | cr_expect(entry1 != NULL,"Expect a tunnel entry be allocated as long as there is space"); 58 | 59 | ret = tunnel_commit(entry1); 60 | cr_expect(ret == PFM_SUCCESS,"Expect the commit to be succesful"); 61 | } 62 | // When the table is full all should fail 63 | ret = tunnel_key_alloc(0,TUNNEL_TYPE_PDUS,&tunnel_key1); 64 | cr_expect(ret == PFM_FAILED,"expect a tunnel key to be allocated"); 65 | 66 | entry1 = tunnel_add(&tunnel_key1); 67 | cr_expect(entry1 == NULL,"Expect a tunnel entry be allocated as long as there is space"); 68 | 69 | ret = tunnel_commit(entry1); 70 | cr_expect(ret == PFM_FAILED); 71 | XXX*/ 72 | 73 | // You cannot modify tunnels with tunnel get 74 | entry1 = tunnel_get(&tunnel_key2); 75 | entry1->remote_ip = pfm_str2ip("255.255.255.255"); 76 | 77 | // Try modifying tunnels 78 | entry1 = tunnel_modify(&tunnel_key2); 79 | entry1->remote_ip = pfm_str2ip("0.0.0.0"); 80 | ret = tunnel_commit(entry1); 81 | cr_expect(ret == PFM_SUCCESS,"Commit is a success after modification"); 82 | entry1 = tunnel_get(&tunnel_key2); 83 | cr_expect(entry1->remote_ip == pfm_str2ip("0.0.0.0"),"Check if modification is recorded"); 84 | 85 | // Remove a tunnel 86 | ret = tunnel_remove(&tunnel_key2); 87 | cr_assert(ret == PFM_SUCCESS,"The tunnel remove is successful"); 88 | ret = tunnel_commit(entry1); 89 | cr_assert(ret == PFM_SUCCESS,"Committed a removed entry"); 90 | entry1 = tunnel_get(&tunnel_key2); 91 | cr_assert(entry1 == NULL,"Tunnel is removed successfully"); 92 | } 93 | 94 | 95 | 96 | int main(int argc, char *argv[]) { 97 | pfm_retval_t ret; 98 | char *v[0]; 99 | int result = 0; 100 | 101 | v[0] = strdup("/home/arv-sajeev/DPDK/dpdk-19.11/examples/pfm/pfm/criterion_tests/e1ap/comps/tunnel_tests/test.c"); 102 | ret = pfm_init(1,v); 103 | printf("Suite setup complete\n"); 104 | 105 | 106 | cr_assert(ret == PFM_SUCCESS); 107 | 108 | struct criterion_test_set *tests = criterion_initialize(); 109 | 110 | if (criterion_handle_args(argc, argv, true)) 111 | result = !criterion_run_all_tests(tests); 112 | 113 | criterion_finalize(tests); 114 | return result; 115 | } 116 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/tunnel/tunnel.h: -------------------------------------------------------------------------------- 1 | #ifndef __TUNNEL_H__ 2 | #define __TUNNEL_H__ 1 3 | #include "pfm.h" 4 | #include "cuup.h" 5 | 6 | typedef enum 7 | { 8 | TUNNEL_TYPE_PDUS, 9 | TUNNEL_TYPE_DRB, 10 | } tunnel_type_t; 11 | 12 | typedef struct 13 | { 14 | unsigned int drb_id:5; 15 | unsigned int is_default:1; 16 | unsigned int is_dl_sdap_hdr_enabled:1; 17 | unsigned int is_ul_sdap_hdr_enabled:1; 18 | uint32_t mapped_flow_idx; // valid only if is_ul_sdap_hdr_enabled 19 | uint32_t mapped_pdus_idx; 20 | } drb_info_t; 21 | 22 | typedef struct 23 | { 24 | unsigned int flow_id:6; 25 | unsigned int r_qos_status:2; 26 | uint32_t mapped_drb_idx; 27 | } flow_info_t; 28 | 29 | typedef struct 30 | { 31 | unsigned int pdus_id:8; 32 | unsigned int flow_count:6; 33 | uint64_t ul_new_flow_detected_bit_map; 34 | flow_info_t flow_list[MAX_FLOWS_PER_PDUS]; 35 | } pdus_info_t; 36 | 37 | typedef struct 38 | { 39 | uint32_t ip_addr; 40 | uint32_t te_id; 41 | } tunnel_key_t; 42 | 43 | typedef struct 44 | { 45 | tunnel_key_t key; 46 | pfm_ip_addr_t remote_ip; 47 | uint32_t remote_te_id; 48 | tunnel_type_t tunnel_type:2; 49 | pfm_bool_t is_row_used:1; 50 | union 51 | { 52 | pdus_info_t pdus_info; 53 | drb_info_t drb_info; 54 | }; 55 | } tunnel_t; 56 | 57 | 58 | const tunnel_t* tunnel_get(tunnel_key_t *key); 59 | tunnel_t * tunnel_add(tunnel_key_t *key); 60 | pfm_retval_t tunnel_remove(tunnel_key_t *key); 61 | tunnel_t * tunnel_modify(tunnel_key_t *key); 62 | pfm_retval_t tunnel_commit(tunnel_t* nt); 63 | void tunnel_print_show(FILE *fp, tunnel_key_t *key); 64 | void tunnel_print_list(FILE *fp, tunnel_type_t ttype); 65 | pfm_retval_t tunnel_key_alloc(pfm_ip_addr_t ip,tunnel_type_t ttype,tunnel_key_t *key); 66 | pfm_retval_t tunnel_remove(tunnel_key_t *key); 67 | pfm_retval_t tunnel_rollback(tunnel_t *nt); 68 | #endif 69 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2010-2014 Intel Corporation 3 | 4 | # binary name 5 | APP = e1ap_bearer_setup.exe 6 | 7 | # all source are stored in SRCS-y 8 | SRCS-y := cuup.c \ 9 | pfm.c \ 10 | pfm_log.c \ 11 | pfm_utils.c \ 12 | ue_ctx.c \ 13 | tunnel.c \ 14 | pdus.c \ 15 | drb.c \ 16 | e1ap_bearer_setup.c \ 17 | 18 | 19 | # Build using pkg-config variables if possible 20 | ifeq ($(shell pkg-config --exists libdpdk && echo 0),0) 21 | 22 | all: shared 23 | .PHONY: shared static 24 | shared: build/$(APP)-shared 25 | ln -sf $(APP)-shared build/$(APP) 26 | static: build/$(APP)-static 27 | ln -sf $(APP)-static build/$(APP) 28 | 29 | PKGCONF ?= pkg-config 30 | 31 | PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) 32 | CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) 33 | CFLAGS += -DALLOW_EXPERIMENTAL_API 34 | LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) 35 | LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) 36 | 37 | build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build 38 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 39 | 40 | build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build 41 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) 42 | 43 | build: 44 | @mkdir -p $@ 45 | 46 | .PHONY: clean 47 | clean: 48 | rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared 49 | test -d build && rmdir -p build || true 50 | 51 | else # Build using legacy build system 52 | 53 | ifeq ($(RTE_SDK),) 54 | $(error "Please define RTE_SDK environment variable") 55 | endif 56 | 57 | # Default target, detect a build directory, by looking for a path with a .config 58 | RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) 59 | 60 | include $(RTE_SDK)/mk/rte.vars.mk 61 | 62 | ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),y) 63 | $(error This application can only operate in a linux environment, \ 64 | please change the definition of the RTE_TARGET environment variable) 65 | endif 66 | 67 | #CFLAGS += -O3 -g -DTRACE -DCONSLOG 68 | CFLAGS += -O3 -g -DTRACE 69 | CFLAGS += -DALLOW_EXPERIMENTAL_API 70 | CFLAGS += $(WERROR_FLAGS) 71 | 72 | include $(RTE_SDK)/mk/rte.extapp.mk 73 | endif 74 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/cuup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "pfm.h" 8 | #include "pfm_comm.h" 9 | #include "pfm_utils.h" 10 | 11 | #define GTP_PORTNO 2152 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/cuup.h: -------------------------------------------------------------------------------- 1 | #ifndef __CUUP_H__ 2 | #define __CUUP_H__ 1 3 | 4 | #define MAX_UE_COUNT 1000 5 | #define MAX_PDUS_PER_UE 4 // range 1 to 256 6 | #define MAX_DRB_PER_PDUS 4 // range 1 to 32 7 | #define MAX_FLOWS_PER_PDUS 4 // rnage 1 to 32 8 | #define MAX_DRB_PER_UE MAX_DRB_PER_PDUS // range 1 to 32 9 | 10 | 11 | #define MAX_TUNNEL_COUNT (MAX_UE_COUNT * MAX_PDUS_PER_UE * MAX_DRB_PER_UE) 12 | 13 | #define NEW_UL_FLOW_NOTIFY_TIMEOUT 100 // in msec 14 | #define NEW_UL_FLOW_NOTIFY_BUNDLE_SIZE 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/drb.c: -------------------------------------------------------------------------------- 1 | #include "pfm.h" 2 | #include "pfm_comm.h" 3 | #include "pfm_log.h" 4 | #include "cuup.h" 5 | #include "tunnel.h" 6 | #include "ue_ctx.h" 7 | #include "drb.h" 8 | #include "e1ap_comm.h" 9 | #include "e1ap_bearer_setup.h" 10 | 11 | static void 12 | drb_setup_succ_rsp_create(tunnel_t* tunnel_entry,drb_setup_succ_rsp_info_t* rsp) 13 | { 14 | rsp->drb_id = tunnel_entry->drb_info.drb_id; 15 | rsp->drb_ul_ip_addr = tunnel_entry->key.ip_addr; 16 | rsp->drb_ul_teid = tunnel_entry->key.te_id; 17 | return; 18 | } 19 | 20 | void 21 | drb_setup_fail_rsp_create(drb_setup_req_info_t *req, 22 | drb_setup_fail_rsp_info_t *rsp, 23 | e1ap_fail_cause_t cause) 24 | { 25 | rsp->drb_id = req->drb_id; 26 | // TD find way to assign cause 27 | rsp->cause = cause; 28 | } 29 | 30 | 31 | 32 | pfm_retval_t 33 | drb_setup(ue_ctx_t* ue_ctx, 34 | drb_setup_req_info_t* req, 35 | drb_setup_succ_rsp_info_t *succ_rsp, 36 | drb_setup_fail_rsp_info_t *fail_rsp) 37 | { 38 | pfm_retval_t ret; 39 | tunnel_key_t tunnel_key; 40 | tunnel_t* tunnel_entry; 41 | 42 | //Assign a tunnel key with drb_dl_ip_addr 43 | ret = tunnel_key_alloc(req->drb_dl_ip_addr,TUNNEL_TYPE_DRB,&tunnel_key); 44 | if (ret == PFM_FAILED) 45 | { 46 | pfm_log_msg(PFM_LOG_ERR,"Error allocating tunnel_key"); 47 | // TD assign cause properly 48 | drb_setup_fail_rsp_create(req,fail_rsp,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL); 49 | return PFM_FAILED; 50 | } 51 | 52 | //Allocate a free entry from the tunnel table 53 | tunnel_entry = tunnel_add(&tunnel_key); 54 | if (tunnel_entry == NULL) 55 | { 56 | pfm_log_msg(PFM_LOG_ERR,"Error allocating tunnel_entry"); 57 | // TD assign cause properly 58 | drb_setup_fail_rsp_create(req,fail_rsp,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL); 59 | return PFM_FAILED; 60 | } 61 | 62 | // Fill the drb details 63 | tunnel_entry->remote_ip = req->drb_dl_ip_addr; 64 | tunnel_entry->remote_te_id = req->drb_dl_teid; 65 | tunnel_entry->tunnel_type = TUNNEL_TYPE_DRB; 66 | tunnel_entry->drb_info.drb_id = req->drb_id; 67 | // TD many more field to fill 68 | 69 | drb_setup_succ_rsp_create(tunnel_entry,succ_rsp); 70 | // Assign new drb_entry to next free slot 71 | ue_ctx->drb_tunnel_list[ue_ctx->drb_count] = tunnel_entry; 72 | ue_ctx->drb_count++; 73 | return PFM_SUCCESS; 74 | } 75 | 76 | 77 | //----------------------------------modify------------------------------ 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/drb.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRB_H__ 2 | #define __DRB_H__ 3 | 4 | 5 | #include "tunnel.h" 6 | #include "ue_ctx.h" 7 | #include "e1ap_comm.h" 8 | #include "e1ap_bearer_setup.h" 9 | #include "cuup.h" 10 | #include "pfm_comm.h" 11 | #include "pfm.h" 12 | #include "cuup.h" 13 | 14 | /********************* 15 | 16 | drb_setup 17 | 18 | Create a new drb entry with given drb_setup_req_info and create it's 19 | drb_setup_succ_rsp_info if required. The entry if created successfully is 20 | assigned to the ue_ctx but not committed.If entry creation failed creation of 21 | failure response must be handled by caller. 22 | 23 | @params 24 | 25 | ue_ctx - pointer to the ue_ctx to populate 26 | req - pointer to the drb_setup_req_info to create drb_entry 27 | succ_rsp - pointer to the drb_setup_succ_rsp_info to populate 28 | if the drb setup was successful 29 | fail_rsp - pointer to the drb_setup_fail_rsp_info to populate in case 30 | drb setup failed 31 | 32 | @returns 33 | 34 | pfm_retval_t - PFM_TRUE - if drb_entry creation was 35 | successful, rsp will be set 36 | 37 | PFM_FALSE - if drb_entry creation was 38 | unsuccessful, rsp will not 39 | be set and fail_rsp must 40 | be set by caller 41 | ***********************/ 42 | pfm_retval_t 43 | drb_setup(ue_ctx_t* ue_ctx, 44 | drb_setup_req_info_t* req, 45 | drb_setup_succ_rsp_info_t* succ_rsp, 46 | drb_setup_fail_rsp_info_t* fail_rsp); 47 | 48 | /********************** 49 | 50 | drb_setup_fail_rsp_create 51 | 52 | Create drb_setup_fail_rsp_info if creation of tunnel entry was unsuccessful 53 | 54 | @params 55 | 56 | req - pointer to drb_setup_req_info that failed drb_create 57 | fail_rsp - pointer to drb_setup_fail_rsp_info that corresponds to 58 | req 59 | cause - The cause for drb_setup failure 60 | 61 | @returns 62 | void 63 | 64 | **********************/ 65 | 66 | void 67 | drb_setup_fail_rsp_create(drb_setup_req_info_t* req, 68 | drb_setup_fail_rsp_info_t *fail_rsp, 69 | e1ap_fail_cause_t cause); 70 | 71 | /************************ 72 | drb_modify 73 | 74 | To modify an existing pdus entry with given drb_setup_req_info and position in 75 | drb_tunnel_list to modify the entry and reassign to list and create it's 76 | responses fail or success depending on result, the drb in the requests are 77 | modified and reassigned but not commited 78 | @params 79 | 80 | ue_ctx - pointer to the ue_ctx to populate 81 | req - pointer to the drb_modify_req_info to create drb_entry 82 | succ_rsp - pointer to the drb_modify_succ_rsp_info to populate 83 | if the drb modification was successful 84 | fail_rsp - pointer to the drb_modify_fail_rsp_info to populate if 85 | the drb modification was unsuccessful 86 | id_x - the index of the entry to be modified in drb_tunnel_list 87 | 88 | @returns 89 | 90 | pfm_retval_t - PFM_TRUE - if drb_entry creation was 91 | successful, rsp will be set 92 | 93 | PFM_FALSE - if drb_entry creation was 94 | unsuccessful, rsp will not 95 | be set and fail_rsp must 96 | be set by caller 97 | **************************/ 98 | 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/e1ap_bearer_setup.c: -------------------------------------------------------------------------------- 1 | #include "pfm.h" 2 | #include "pfm_log.h" 3 | #include "pfm_utils.h" 4 | #include "cuup.h" 5 | #include "e1ap_bearer_setup.h" 6 | #include "e1ap_comm.h" 7 | #include "tunnel.h" 8 | #include "ue_ctx.h" 9 | #include "pdus.h" 10 | #include "drb.h" 11 | 12 | 13 | 14 | // Assuming that if things go wrong before even an id is allocated the 15 | // the cuup_ue_id is set as 0 for the failure response 16 | static void 17 | e1ap_bearer_setup_fail(uint32_t cucp_ue_id, 18 | uint32_t cuup_ue_id, 19 | e1ap_fail_cause_t cause, 20 | e1ap_bearer_ctx_setup_rsp_t *rsp) 21 | { 22 | pfm_log_msg(PFM_LOG_ERR,"bearer setup failure"); 23 | rsp->cuup_ue_id = cuup_ue_id; 24 | rsp->cucp_ue_id = cucp_ue_id; 25 | rsp->cause = cause; 26 | rsp->pdus_setup_succ_count = 0; 27 | return; 28 | } 29 | 30 | 31 | pfm_retval_t 32 | e1ap_bearer_ctx_setup(e1ap_bearer_ctx_setup_req_t *req, 33 | e1ap_bearer_ctx_setup_rsp_t *rsp) 34 | { 35 | int i; 36 | pfm_retval_t ret; 37 | ue_ctx_t *ue_ctx; 38 | uint32_t ue_id; 39 | char ip_str[STR_IP_ADDR_SIZE]; 40 | // Allocate a ue_id 41 | ret = ue_ctx_id_alloc(&ue_id); 42 | if (ret == PFM_FAILED) 43 | { 44 | pfm_log_msg(PFM_LOG_ERR,"Error allocating ue_id"); 45 | e1ap_bearer_setup_fail(req->cucp_ue_id,MAX_UE_COUNT,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL,rsp); 46 | return PFM_FAILED; 47 | } 48 | 49 | // Allocate an empty ue_ctx entry 50 | ue_ctx = ue_ctx_add(ue_id); 51 | if (ue_ctx == NULL) 52 | { 53 | pfm_log_msg(PFM_LOG_ERR,"Error allocating ue_ctx"); 54 | ue_ctx_id_free(&ue_id); 55 | e1ap_bearer_setup_fail(req->cucp_ue_id,MAX_UE_COUNT,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL,rsp); 56 | return PFM_FAILED; 57 | } 58 | 59 | // Fill up the basic ue details 60 | ue_ctx->cucp_ue_id = req->cucp_ue_id; 61 | ue_ctx->pdus_count = 0; 62 | ue_ctx->drb_count = 0; 63 | ue_ctx->new_ul_flow_detected_count = 0; 64 | 65 | // Setup the rsp values we currently know 66 | rsp->cuup_ue_id = ue_ctx->cuup_ue_id; 67 | rsp->cucp_ue_id = ue_ctx->cucp_ue_id; 68 | // Cause is 0 for success 69 | rsp->cause = 0; 70 | rsp->pdus_setup_succ_count = 0; 71 | rsp->pdus_setup_fail_count = 0; 72 | 73 | 74 | // Service each pdus_create_request 75 | for (i = 0;i < req->pdus_count;i++) 76 | { 77 | // Storing pointers to make stuff easier 78 | pdus_setup_succ_rsp_info_t* succ_rsp = 79 | &(rsp->pdus_succ_list[rsp->pdus_setup_succ_count]); 80 | pdus_setup_fail_rsp_info_t* fail_rsp = 81 | &(rsp->pdus_fail_list[rsp->pdus_setup_fail_count]); 82 | 83 | // service each pdus request 84 | ret = pdus_setup(ue_ctx,&(req->pdus_list[i]),succ_rsp,fail_rsp); 85 | // If failed make failed rsp 86 | if (ret == PFM_FAILED) 87 | { 88 | pfm_log_msg(PFM_LOG_ERR,"Error creating PDUS entry" 89 | "pdus_id : %u remote-ip : %s" 90 | " remote-te-id : %u", 91 | req->pdus_list[i].pdus_id, 92 | pfm_ip2str(req->pdus_list[i].pdus_ul_ip_addr,ip_str), 93 | req->pdus_list[i].pdus_ul_teid); 94 | rsp->pdus_setup_fail_count++; 95 | continue; 96 | } 97 | rsp->pdus_setup_succ_count++; 98 | } 99 | // If all pdus_reqs failed 100 | 101 | if (rsp->pdus_setup_succ_count == 0) 102 | { 103 | pfm_log_msg(PFM_LOG_ERR,"all pdus requests failed ue_id %d", 104 | ue_id); 105 | ue_ctx_remove(ue_id); 106 | ue_ctx_commit(ue_ctx); 107 | e1ap_bearer_setup_fail(req->cucp_ue_id,ue_ctx->cucp_ue_id,FAIL_CAUSE_RNL_UNSPECIFIED,rsp); 108 | return PFM_FAILED; 109 | } 110 | ret = ue_ctx_commit(ue_ctx); 111 | if (ret == PFM_FAILED) 112 | { 113 | pfm_log_msg(PFM_LOG_ERR,"Error committing ue_ctx ue_id %d", 114 | ue_id); 115 | ue_ctx_remove(ue_id); 116 | ue_ctx_commit(ue_ctx); 117 | e1ap_bearer_setup_fail(req->cucp_ue_id,ue_id,FAIL_CAUSE_RNL_UNSPECIFIED,rsp); 118 | } 119 | return ret; 120 | } 121 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/e1ap_bearer_setup.h: -------------------------------------------------------------------------------- 1 | #ifndef __E1AP_BEARER_SETUP_H__ 2 | #define __E1AP_BEARER_SETUP_H__ 1 3 | 4 | #include "cuup.h" 5 | #include "e1ap_comm.h" 6 | 7 | // BEARER CONTEXT SETUP REQUEST Sec 9.2.2.1 of 3GPP TS 38.463 8 | typedef struct 9 | { 10 | uint32_t cucp_ue_id; 11 | 12 | // PDU Session Resource To Setup List 9.3.3.2 13 | uint8_t pdus_count; 14 | pdus_setup_req_info_t pdus_list[MAX_PDUS_PER_UE]; 15 | } e1ap_bearer_ctx_setup_req_t; 16 | 17 | // BEARER CONTEXT SETUP RESPONSE. sec 9.2.2.2 of 3GPP TS 38.463 18 | typedef struct 19 | { 20 | uint32_t cucp_ue_id; 21 | uint32_t cuup_ue_id; 22 | e1ap_fail_cause_t cause; // set to 0 is sucess 23 | uint8_t pdus_setup_succ_count; 24 | uint8_t pdus_setup_fail_count; 25 | pdus_setup_succ_rsp_info_t pdus_succ_list[MAX_PDUS_PER_UE]; 26 | pdus_setup_fail_rsp_info_t pdus_fail_list[MAX_PDUS_PER_UE]; 27 | } e1ap_bearer_ctx_setup_rsp_t; 28 | 29 | 30 | pfm_retval_t 31 | e1ap_bearer_ctx_setup(e1ap_bearer_ctx_setup_req_t *req,e1ap_bearer_ctx_setup_rsp_t *rsp); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/ipcmd.txt: -------------------------------------------------------------------------------- 1 | 2 | ip [ OPTIONS ] OBJECT { COMMAND | help } 3 | 4 | where 5 | 6 | OBJECT = link(l), address(a), route(r), neigh(n), rule(ru) 7 | 8 | 9 | use 'ip OBJECT help' the get options 10 | 11 | 1. Show IP address of eth0 12 | 13 | ip addr show dev eth0 14 | 15 | 2. Assigne IP address to eth0 16 | 17 | ip addr add 192.168.121.45/24 dev eth0 18 | 19 | 3. Remove IP Address from eth0 20 | 21 | ip addr add 192.168.121.45/24 dev eth0 22 | 23 | 4. Bring eth0 interface up 24 | 25 | ip link set eth0 up 26 | 27 | 5. Dispay route 28 | 29 | ip route list 30 | 31 | 6. Dispaly route of a specific network 32 | 33 | ip r list 172.17.0.0/16 34 | 35 | 7. Add new route 36 | 37 | ip r add 172.17.0.0/16 dev eth0 38 | 39 | 8. Add default route 40 | 41 | ip r add default via 192.168.121.1 dev eth0 42 | 43 | 9. Delete route 44 | 45 | ip route del default 46 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/pdus.c: -------------------------------------------------------------------------------- 1 | #include "pfm.h" 2 | #include "pfm_comm.h" 3 | #include "pfm_log.h" 4 | #include "cuup.h" 5 | #include "tunnel.h" 6 | #include "ue_ctx.h" 7 | #include "pdus.h" 8 | #include "drb.h" 9 | #include "e1ap_comm.h" 10 | #include "e1ap_bearer_setup.h" 11 | static void 12 | pdus_setup_succ_rsp_create(tunnel_t *tunnel_entry,pdus_setup_succ_rsp_info_t *succ_rsp) 13 | { 14 | succ_rsp->pdus_id = tunnel_entry->pdus_info.pdus_id; 15 | succ_rsp->drb_setup_succ_count = 0; 16 | succ_rsp->drb_setup_fail_count = 0; 17 | succ_rsp->pdus_dl_ip_addr = tunnel_entry->key.ip_addr; 18 | succ_rsp->pdus_dl_teid = tunnel_entry->key.te_id; 19 | return; 20 | } 21 | 22 | void 23 | pdus_setup_fail_rsp_create(pdus_setup_req_info_t* req, 24 | pdus_setup_fail_rsp_info_t* fail_rsp, 25 | e1ap_fail_cause_t cause) 26 | { 27 | fail_rsp->pdus_id = req->pdus_id; 28 | // TD how to assign cause 29 | fail_rsp->cause = cause; 30 | return; 31 | } 32 | 33 | 34 | pfm_retval_t 35 | pdus_setup(ue_ctx_t* ue_ctx, 36 | pdus_setup_req_info_t* req, 37 | pdus_setup_succ_rsp_info_t *succ_rsp, 38 | pdus_setup_fail_rsp_info_t *fail_rsp) 39 | { 40 | pfm_retval_t ret; 41 | tunnel_key_t tunnel_key; 42 | tunnel_t *tunnel_entry; 43 | 44 | drb_setup_succ_rsp_info_t* drb_succ_rsp; 45 | drb_setup_fail_rsp_info_t* drb_fail_rsp; 46 | 47 | // Assign a tunnel key with pdus_ul_ip_addr 48 | ret = tunnel_key_alloc(req->pdus_ul_ip_addr,TUNNEL_TYPE_PDUS,&tunnel_key); 49 | if (ret == PFM_FAILED) 50 | { 51 | pfm_log_msg(PFM_LOG_ERR,"Error allocating tunnel_key"); 52 | // TD assign cause properly 53 | pdus_setup_fail_rsp_create(req,fail_rsp,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL); 54 | return PFM_FAILED; 55 | } 56 | 57 | // Allocate a free entry from the tunnel table 58 | 59 | tunnel_entry = tunnel_add(&tunnel_key); 60 | if (tunnel_entry == NULL) 61 | { 62 | pfm_log_msg(PFM_LOG_ERR,"Error allocating tunnel_entry"); 63 | // TD assign cause properly 64 | tunnel_key_free(&tunnel_key); 65 | pdus_setup_fail_rsp_create(req,fail_rsp,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL); 66 | return PFM_FAILED; 67 | } 68 | 69 | // Fill in the pdus details to the entry 70 | tunnel_entry->remote_ip = req->pdus_ul_ip_addr; 71 | tunnel_entry->remote_te_id = req->pdus_ul_teid; 72 | tunnel_entry->tunnel_type = TUNNEL_TYPE_PDUS; 73 | tunnel_entry->pdus_info.pdus_id = req->pdus_id; 74 | 75 | // Setup up the succ_rsp since it's gone fine so far 76 | // Rest of the info is added as the drb's are processed 77 | 78 | pdus_setup_succ_rsp_create(tunnel_entry,succ_rsp); 79 | 80 | for (int i = 0;i < req->drb_count;i++) { 81 | // Storing frequently used pointers to make the variable names smaller 82 | drb_succ_rsp = &(succ_rsp->drb_succ_list[succ_rsp->drb_setup_succ_count]); 83 | drb_fail_rsp = &(succ_rsp->drb_fail_list[succ_rsp->drb_setup_fail_count]); 84 | 85 | // Process this drb 86 | ret = drb_setup(ue_ctx,&(req->drb_list[i]),drb_succ_rsp,drb_fail_rsp); 87 | 88 | // If failed log and increment the drb_setup_fail_count 89 | if (ret == PFM_FAILED){ 90 | pfm_log_msg(PFM_LOG_ERR,"Error creating DRB entry"); 91 | succ_rsp->drb_setup_fail_count++; 92 | continue; 93 | } 94 | succ_rsp->drb_setup_succ_count++; 95 | } 96 | // If all drb requests fail consider the pdu request a fail 97 | if (succ_rsp->drb_setup_fail_count == req->drb_count) 98 | { 99 | pfm_log_msg(PFM_LOG_ERR, 100 | "all drb_req in pdus_req failed pdus id :: %s:", 101 | req->pdus_id); 102 | tunnel_remove(&tunnel_key); 103 | tunnel_commit(tunnel_entry); 104 | 105 | pdus_setup_fail_rsp_create(req,fail_rsp,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL); 106 | return PFM_FAILED; 107 | } 108 | 109 | // Assign tunnel_entry to the next vacant spot 110 | ue_ctx->pdus_tunnel_list[ue_ctx->pdus_count] = tunnel_entry; 111 | ue_ctx->pdus_count++; 112 | return PFM_SUCCESS; 113 | } 114 | 115 | 116 | //---------------------------------------------------pdus_modify------------------------ 117 | 118 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/pdus.h: -------------------------------------------------------------------------------- 1 | #ifndef __PDUS_H__ 2 | #define __PDUS_H__ 3 | 4 | #include "tunnel.h" 5 | #include "ue_ctx.h" 6 | #include "e1ap_comm.h" 7 | #include "e1ap_bearer_setup.h" 8 | #include "cuup.h" 9 | #include "pfm_comm.h" 10 | #include "pfm.h" 11 | #include "cuup.h" 12 | 13 | /********************* 14 | 15 | pdus_setup 16 | 17 | Create a new pdus entry with given pdus_setup_req_info and create it's 18 | pdus_setup_succ_rsp_info if required. The entry if created successfully is 19 | assigned to the ue_ctx but not committed. The fail_rsp is also created calling 20 | pdus_setup_fail_rsp_create if failure occurred within pdus_setup if the failure 21 | to setup pdus occurred outside pdus_setup fail_rsp should be taken care of manually 22 | 23 | 24 | @params 25 | 26 | ue_ctx - pointer to the ue_ctx to populate 27 | req - pointer to the pdus_setup_req_info to create pdus_entry 28 | succ_rsp - pointer to the pdus_setup_succ_rsp_info to populate 29 | if the pdu setup was successful 30 | fail_rsp - pointer to the pdus_setup_succ_rsp_info to populate 31 | if pdu setup was unsuccessful 32 | 33 | @returns 34 | 35 | pfm_retval_t - PFM_TRUE - if pdus_entry creation was 36 | successful, rsp will be set 37 | 38 | PFM_FALSE - if pdus_entry creation was 39 | unsuccessful, rsp will not 40 | be set and fail_rsp must 41 | be set by caller 42 | ***********************/ 43 | pfm_retval_t 44 | pdus_setup(ue_ctx_t* ue_ctx, 45 | pdus_setup_req_info_t* req, 46 | pdus_setup_succ_rsp_info_t* succ_rsp, 47 | pdus_setup_fail_rsp_info_t* fail_rsp); 48 | 49 | /********************** 50 | 51 | pdus_setup_fail_rsp_create 52 | 53 | Create pdus_setup_fail_rsp_info if creation of tunnel entry was unsuccessful 54 | 55 | @params 56 | 57 | req - pointer to pdus_setup_req_info that failed pdus_create 58 | fail_rsp - pointer to pdus_setup_fail_rsp_info that corresponds to 59 | req 60 | cause - cause that caused failure of pdus_setup 61 | 62 | @returns 63 | void 64 | 65 | **********************/ 66 | 67 | void 68 | pdus_setup_fail_rsp_create(pdus_setup_req_info_t* req, 69 | pdus_setup_fail_rsp_info_t *fail_rsp, 70 | e1ap_fail_cause_t cause); 71 | 72 | /************************ 73 | pdus_modify 74 | 75 | To modify an existing pdus entry with given pdus_setup_req_info and positon in 76 | pdus_tunnel_list to modify the entry and reassign to list and create it's 77 | responses fail or success depending on result, the pdus and its associated drb in the 78 | request are modified but not committed 79 | 80 | @params 81 | 82 | ue_ctx - pointer to the ue_ctx to populate 83 | req - pointer to the pdus_modify_req_info to create pdus_entry 84 | succ_rsp - pointer to the pdus_modify_succ_rsp_info to populate 85 | if the pdus modification was successful 86 | fail_rsp - pointer to the pdus_modify_fail_rsp_info to populate if 87 | the pdus modification was unsuccessful 88 | id_x - the index of the entry to be modified in pdus_tunnel_list 89 | 90 | @returns 91 | 92 | pfm_retval_t - PFM_TRUE - if pdus_entry creation was 93 | successful, rsp will be set 94 | 95 | PFM_FALSE - if pdus_entry creation was 96 | unsuccessful, rsp will not 97 | be set and fail_rsp must 98 | be set by caller 99 | **************************/ 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/pfm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "pfm.h" 6 | #include "pfm_comm.h" 7 | 8 | pfm_retval_t pfm_init(int argc, char *argv[]) 9 | { 10 | int ret; 11 | int lcore_count; 12 | 13 | ret = rte_eal_init(argc, argv); 14 | if (0 > ret) 15 | { 16 | pfm_log_rte_err(PFM_LOG_EMERG, 17 | "rte_eal_init(argc=%d,argc=%p) failed. Terminating", 18 | argc, argv); 19 | return PFM_FAILED; 20 | } 21 | pfm_trace_msg("EAL Initialized"); 22 | 23 | lcore_count = rte_lcore_count(); 24 | pfm_trace_msg("Detected %d lcores",lcore_count); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/pfm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_H__ 2 | #define __PFM_H__ 1 3 | 4 | #include 5 | #include "pfm_log.h" 6 | 7 | typedef enum 8 | { 9 | PROTOCOL_UDP = 17 10 | } pfm_protocol_t; 11 | 12 | typedef uint32_t pfm_ip_addr_t; 13 | 14 | typedef enum 15 | { 16 | PFM_SUCCESS, 17 | PFM_FAILED, 18 | PFM_NOT_FOUND 19 | } pfm_retval_t; 20 | 21 | typedef enum 22 | { 23 | PFM_FALSE = 0, 24 | PFM_TRUE = 1 25 | } pfm_bool_t; 26 | 27 | pfm_retval_t pfm_init(int argc, char *argv[]); 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/pfm_comm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_COMM_H__ 2 | #define __PFM_COMM_H__ 1 3 | #include 4 | #include "pfm.h" 5 | #define MAX_LCORES 32 6 | #define MAX_LINK_COUNT 5 7 | #define LAST_LINK_ID MAX_LINK_COUNT 8 | #define MAX_KNI_PORTS 5 9 | #define MAX_LOCAL_IP_COUNT (MAX_KNI_PORTS*2) 10 | 11 | #define MBUF_COUNT 4096 12 | #define MBUF_CASHE_SIZE 128 13 | #define MBUF_PRIV_SIZE 0 14 | 15 | /* DPDK object names */ 16 | #define MBUF_NAME "MBUF" 17 | #define TX_RING_NAME "TXRING" 18 | #define RX_RING_NAME "RXRING" 19 | #define DIST_NAME "DISTNAME" 20 | 21 | #define TX_RING_SIZE 64 22 | #define RX_RING_SIZE TX_RING_SIZE 23 | #define TX_BURST_SIZE 32 24 | #define RX_BURST_SIZE TX_BURST_SIZE 25 | 26 | #define MAC_ADDR_SIZE RTE_ETHER_ADDR_LEN 27 | #define IP_ADDR_SIZE 4 28 | #define STR_IP_ADDR_SIZE 20 29 | #define DEFAULT_MTU_SIZE 1500 30 | #define DEFAULT_MIN_MTU_SIZE 68 31 | #define DEFAULT_MAX_MTU_SIZE 65535 32 | 33 | #define TIMER_RESOLUTION_CYCLES 20000000ULL 34 | 35 | #define ARP_TABLE_SIZE 32 36 | 37 | enum { 38 | LCORE_MAIN = 0, 39 | LCORE_RXLOOP = 1, 40 | LCORE_TXLOOP = 2, 41 | LCORE_DISTRIBUTOR = 3, 42 | LCORE_WORKER = 4, 43 | LCORE_MIN_LCORE_COUNT 44 | }; 45 | 46 | #define MAX_WORKERS (MAX_LCORES - LCORE_WORKER) 47 | typedef enum 48 | { 49 | ADMSTATE_UNLOCKED, 50 | ADMSTATE_LOCKED, 51 | } admin_state_t; 52 | 53 | typedef enum 54 | { 55 | OPSSTATE_NOTCONFIGURED, 56 | OPSSTATE_ENABLED, 57 | OPSSTATE_DISABLED, 58 | OPSSTATE_FAULTY 59 | } ops_state_t; 60 | 61 | typedef struct { 62 | int kniIdx; 63 | pfm_ip_addr_t ip_addr; 64 | pfm_ip_addr_t network_mask; 65 | pfm_ip_addr_t default_gateway_ip; 66 | } local_ip_addr_t; 67 | 68 | typedef struct { 69 | int lcore_count; 70 | int kni_count; 71 | int local_ip_count; 72 | local_ip_addr_t local_ip_addr_list[MAX_LOCAL_IP_COUNT]; 73 | struct rte_mempool *mbuf_pool; 74 | struct rte_ring *rx_ring_ptr ; 75 | struct rte_ring *tx_ring_ptr ; 76 | struct rte_kni *kni_ptr; 77 | struct rte_distributor *dist_ptr; 78 | } sys_info_t; 79 | 80 | 81 | extern volatile pfm_bool_t force_quit_g; /* all loops will use this 82 | varable to determin the looping need to continue 83 | or not. By setting this varlbale to TRUE, all loops 84 | can be terminated */ 85 | extern sys_info_t sys_info_g; 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/pfm_utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pfm.h" 7 | #include "pfm_comm.h" 8 | #include "pfm_log.h" 9 | #include "pfm_utils.h" 10 | 11 | pfm_ip_addr_t pfm_str2ip(const char *ip_str) 12 | { 13 | pfm_ip_addr_t ipn; // IP in network order 14 | pfm_ip_addr_t iph; // IP in host order 15 | int ret; 16 | 17 | ret = inet_pton(AF_INET,ip_str,&ipn); 18 | if (1 != ret) 19 | { 20 | pfm_log_std_err(PFM_LOG_WARNING, 21 | "Failed to convert IP=[%s] to " 22 | "pfm_ip_addr_t format", ip_str); 23 | return 0; 24 | } 25 | iph = ntohl(ipn); 26 | return iph; 27 | } 28 | 29 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_str) 30 | { 31 | pfm_ip_addr_t ipn; // IP in network order 32 | 33 | ipn = htonl(iph); 34 | const char *ret = inet_ntop(AF_INET,&ipn,ip_str,STR_IP_ADDR_SIZE); 35 | if (NULL == ret) 36 | { 37 | pfm_log_std_err(PFM_LOG_ERR, 38 | "Failed to IP=[0x%0X] to string format",iph); 39 | return NULL; 40 | } 41 | return ip_str; 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/pfm_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_UTILS_H__ 2 | #define __PFM_UTILS_H__ 1 3 | #include "pfm.h" 4 | 5 | pfm_ip_addr_t pfm_str2ip(const char *ip_str); 6 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_addr_str); 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/run.sh: -------------------------------------------------------------------------------- 1 | sudo ./build/cuup.exe --lcore '0@0,1@1,2@0,3@1,4@0,5@1' --syslog local6 2 | 3 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "pfm.h" 5 | #include "pfm_log.h" 6 | #include "pfm_utils.h" 7 | 8 | #include "cuup.h" 9 | #include "tunnel.h" 10 | #include "ue_ctx.h" 11 | #include 12 | #include 13 | 14 | void setup() 15 | { 16 | printf("In test suite setup\n"); 17 | pfm_retval_t ret; 18 | char *v[0]; 19 | v[0] = strdup("/home/arv-sajeev/DPDK/dpdk-19.11/examples/pfm/criterion_tests/e1ap/components/build/tunnel_test.exe"); 20 | 21 | ret = pfm_init(1,v); 22 | cr_assert(ret == PFM_SUCCESS); 23 | printf("Suite setup comlete\n"); 24 | } 25 | 26 | 27 | void cleanup() 28 | { 29 | int ret; 30 | printf("In test suite cleanup\n"); 31 | ret = rte_eal_cleanup(); 32 | cr_assert(ret == 0,"test suite setup complete\n"); 33 | } 34 | 35 | 36 | TestSuite(ue_ctx_test_suite,.init = setup,.fini = cleanup, 37 | .description = "Test to verify correctness of UE context interface"); 38 | 39 | 40 | Test(ue_ctx_test_suite,addition,.description = "Tests allocating a new ue_ctx") 41 | { 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/tunnel.h: -------------------------------------------------------------------------------- 1 | #ifndef __TUNNEL_H__ 2 | #define __TUNNEL_H__ 1 3 | #include "pfm.h" 4 | #include "cuup.h" 5 | 6 | typedef enum 7 | { 8 | TUNNEL_TYPE_PDUS, 9 | TUNNEL_TYPE_DRB, 10 | } tunnel_type_t; 11 | 12 | typedef struct 13 | { 14 | unsigned int drb_id:5; 15 | unsigned int is_default:1; 16 | unsigned int is_dl_sdap_hdr_enabled:1; 17 | unsigned int is_ul_sdap_hdr_enabled:1; 18 | uint32_t mapped_flow_idx; // valid only if is_ul_sdap_hdr_enabled 19 | uint32_t mapped_pdus_idx; 20 | } drb_info_t; 21 | 22 | typedef struct 23 | { 24 | unsigned int flow_id:6; 25 | unsigned int r_qos_status:2; 26 | uint32_t mapped_drb_idx; 27 | } flow_info_t; 28 | 29 | typedef struct 30 | { 31 | unsigned int pdus_id:8; 32 | unsigned int flow_count:6; 33 | uint64_t ul_new_flow_detected_bit_map; 34 | flow_info_t flow_list[MAX_FLOWS_PER_PDUS]; 35 | } pdus_info_t; 36 | 37 | typedef struct 38 | { 39 | uint32_t ip_addr; 40 | uint32_t te_id; 41 | } tunnel_key_t; 42 | 43 | typedef struct 44 | { 45 | tunnel_key_t key; 46 | pfm_ip_addr_t remote_ip; 47 | uint32_t remote_te_id; 48 | tunnel_type_t tunnel_type:2; 49 | pfm_bool_t is_row_used:1; 50 | union 51 | { 52 | pdus_info_t pdus_info; 53 | drb_info_t drb_info; 54 | }; 55 | } tunnel_t; 56 | 57 | 58 | const tunnel_t* tunnel_get(tunnel_key_t *key); 59 | tunnel_t * tunnel_add(tunnel_key_t *key); 60 | pfm_retval_t tunnel_remove(tunnel_key_t *key); 61 | tunnel_t * tunnel_modify(tunnel_key_t *key); 62 | pfm_retval_t tunnel_commit(tunnel_t* nt); 63 | void tunnel_print_show(FILE *fp, tunnel_key_t *key); 64 | void tunnel_print_list(FILE *fp, tunnel_type_t ttype); 65 | pfm_retval_t tunnel_key_alloc(pfm_ip_addr_t ip,tunnel_type_t ttype,tunnel_key_t *key); 66 | pfm_retval_t tunnel_key_free(tunnel_key_t *tunnel_key); 67 | #endif 68 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/components/ue_ctx/ue_ctx.h: -------------------------------------------------------------------------------- 1 | #ifndef __UE_CTX_H__ 2 | #define __UE_CTX_H__ 1 3 | 4 | #include "tunnel.h" 5 | 6 | 7 | typedef struct 8 | { 9 | uint32_t cuup_ue_id; // 32 bit gNB-CU-UP UE E1AP ID 10 | uint32_t cucp_ue_id; // 32 bit gNB-CU-CP UE E1AP ID 11 | uint8_t pdus_count:8; // PDU Session count 12 | uint8_t drb_count:5; 13 | uint8_t new_ul_flow_detected_count:5; 14 | pfm_bool_t is_row_used:1; 15 | tunnel_t * pdus_tunnel_list[MAX_PDUS_PER_UE]; 16 | tunnel_t * drb_tunnel_list[MAX_DRB_PER_UE]; 17 | } ue_ctx_t; 18 | 19 | ue_ctx_t * ue_ctx_add(uint32_t ue_id); 20 | pfm_retval_t ue_ctx_remove(uint32_t ue_id); 21 | ue_ctx_t * ue_ctx_modify(uint32_t ue_id); 22 | pfm_retval_t ue_ctx_commit(ue_ctx_t *new_ctx); 23 | const ue_ctx_t * ue_ctx_get(uint32_t ue_id); 24 | void ue_ctx_print_list(FILE *fp); 25 | void ue_ctx_print_show(FILE *fp, uint32_t ue_id); 26 | pfm_retval_t ue_ctx_id_alloc(uint32_t *ue_id); 27 | pfm_retval_t ue_ctx_id_free(uint32_t *ue_id); 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2010-2014 Intel Corporation 3 | 4 | # binary name 5 | APP = e1ap_bearer_setup.exe 6 | 7 | # all source are stored in SRCS-y 8 | SRCS-y := cuup.c \ 9 | pfm.c \ 10 | pfm_log.c \ 11 | pfm_utils.c \ 12 | ue_ctx.c \ 13 | tunnel.c \ 14 | pdus.c \ 15 | drb.c \ 16 | e1ap_bearer_setup.c \ 17 | 18 | 19 | # Build using pkg-config variables if possible 20 | ifeq ($(shell pkg-config --exists libdpdk && echo 0),0) 21 | 22 | all: shared 23 | .PHONY: shared static 24 | shared: build/$(APP)-shared 25 | ln -sf $(APP)-shared build/$(APP) 26 | static: build/$(APP)-static 27 | ln -sf $(APP)-static build/$(APP) 28 | 29 | PKGCONF ?= pkg-config 30 | 31 | PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) 32 | CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) 33 | CFLAGS += -DALLOW_EXPERIMENTAL_API 34 | LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) 35 | LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) 36 | 37 | build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build 38 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 39 | 40 | build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build 41 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) 42 | 43 | build: 44 | @mkdir -p $@ 45 | 46 | .PHONY: clean 47 | clean: 48 | rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared 49 | test -d build && rmdir -p build || true 50 | 51 | else # Build using legacy build system 52 | 53 | ifeq ($(RTE_SDK),) 54 | $(error "Please define RTE_SDK environment variable") 55 | endif 56 | 57 | # Default target, detect a build directory, by looking for a path with a .config 58 | RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) 59 | 60 | include $(RTE_SDK)/mk/rte.vars.mk 61 | 62 | ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),y) 63 | $(error This application can only operate in a linux environment, \ 64 | please change the definition of the RTE_TARGET environment variable) 65 | endif 66 | 67 | #CFLAGS += -O3 -g -DTRACE -DCONSLOG 68 | CFLAGS += -O3 -g -DTRACE 69 | CFLAGS += -DALLOW_EXPERIMENTAL_API 70 | CFLAGS += $(WERROR_FLAGS) 71 | 72 | include $(RTE_SDK)/mk/rte.extapp.mk 73 | endif 74 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/cuup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "pfm.h" 8 | #include "pfm_comm.h" 9 | #include "pfm_utils.h" 10 | 11 | #define GTP_PORTNO 2152 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/cuup.h: -------------------------------------------------------------------------------- 1 | #ifndef __CUUP_H__ 2 | #define __CUUP_H__ 1 3 | 4 | #define MAX_UE_COUNT 1000 5 | #define MAX_PDUS_PER_UE 4 // range 1 to 256 6 | #define MAX_DRB_PER_PDUS 4 // range 1 to 32 7 | #define MAX_FLOWS_PER_PDUS 4 // rnage 1 to 32 8 | #define MAX_DRB_PER_UE MAX_DRB_PER_PDUS // range 1 to 32 9 | 10 | 11 | #define MAX_TUNNEL_COUNT (MAX_UE_COUNT * MAX_PDUS_PER_UE * MAX_DRB_PER_UE) 12 | 13 | #define NEW_UL_FLOW_NOTIFY_TIMEOUT 100 // in msec 14 | #define NEW_UL_FLOW_NOTIFY_BUNDLE_SIZE 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/drb.c: -------------------------------------------------------------------------------- 1 | #include "pfm.h" 2 | #include "pfm_comm.h" 3 | #include "pfm_log.h" 4 | #include "cuup.h" 5 | #include "tunnel.h" 6 | #include "ue_ctx.h" 7 | #include "drb.h" 8 | #include "e1ap_comm.h" 9 | #include "e1ap_bearer_setup.h" 10 | 11 | static void 12 | drb_setup_succ_rsp_create(tunnel_t* tunnel_entry,drb_setup_succ_rsp_info_t* rsp) 13 | { 14 | rsp->drb_id = tunnel_entry->drb_info.drb_id; 15 | rsp->drb_ul_ip_addr = tunnel_entry->key.ip_addr; 16 | rsp->drb_ul_teid = tunnel_entry->key.te_id; 17 | return; 18 | } 19 | 20 | void 21 | drb_setup_fail_rsp_create(drb_setup_req_info_t *req, 22 | drb_setup_fail_rsp_info_t *rsp, 23 | e1ap_fail_cause_t cause) 24 | { 25 | rsp->drb_id = req->drb_id; 26 | // TD find way to assign cause 27 | rsp->cause = cause; 28 | } 29 | 30 | 31 | 32 | pfm_retval_t 33 | drb_setup(ue_ctx_t* ue_ctx, 34 | drb_setup_req_info_t* req, 35 | drb_setup_succ_rsp_info_t *succ_rsp, 36 | drb_setup_fail_rsp_info_t *fail_rsp) 37 | { 38 | pfm_retval_t ret; 39 | tunnel_key_t tunnel_key; 40 | tunnel_t* tunnel_entry; 41 | 42 | //Assign a tunnel key with drb_dl_ip_addr 43 | ret = tunnel_key_alloc(req->drb_dl_ip_addr,TUNNEL_TYPE_DRB,&tunnel_key); 44 | if (ret == PFM_FAILED) 45 | { 46 | pfm_log_msg(PFM_LOG_ERR,"Error allocating tunnel_key"); 47 | // TD assign cause properly 48 | drb_setup_fail_rsp_create(req,fail_rsp,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL); 49 | return PFM_FAILED; 50 | } 51 | 52 | //Allocate a free entry from the tunnel table 53 | tunnel_entry = tunnel_add(&tunnel_key); 54 | if (tunnel_entry == NULL) 55 | { 56 | pfm_log_msg(PFM_LOG_ERR,"Error allocating tunnel_entry"); 57 | // TD assign cause properly 58 | drb_setup_fail_rsp_create(req,fail_rsp,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL); 59 | return PFM_FAILED; 60 | } 61 | 62 | // Fill the drb details 63 | tunnel_entry->remote_ip = req->drb_dl_ip_addr; 64 | tunnel_entry->remote_te_id = req->drb_dl_teid; 65 | tunnel_entry->tunnel_type = TUNNEL_TYPE_DRB; 66 | tunnel_entry->drb_info.drb_id = req->drb_id; 67 | // TD many more field to fill 68 | 69 | drb_setup_succ_rsp_create(tunnel_entry,succ_rsp); 70 | // Assign new drb_entry to next free slot 71 | ue_ctx->drb_tunnel_list[ue_ctx->drb_count] = tunnel_entry; 72 | ue_ctx->drb_count++; 73 | return PFM_SUCCESS; 74 | } 75 | 76 | 77 | //----------------------------------modify------------------------------ 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/drb.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRB_H__ 2 | #define __DRB_H__ 3 | 4 | 5 | #include "tunnel.h" 6 | #include "ue_ctx.h" 7 | #include "e1ap_comm.h" 8 | #include "e1ap_bearer_setup.h" 9 | #include "cuup.h" 10 | #include "pfm_comm.h" 11 | #include "pfm.h" 12 | #include "cuup.h" 13 | 14 | /********************* 15 | 16 | drb_setup 17 | 18 | Create a new drb entry with given drb_setup_req_info and create it's 19 | drb_setup_succ_rsp_info if required. The entry if created successfully is 20 | assigned to the ue_ctx but not committed.If entry creation failed creation of 21 | failure response must be handled by caller. 22 | 23 | @params 24 | 25 | ue_ctx - pointer to the ue_ctx to populate 26 | req - pointer to the drb_setup_req_info to create drb_entry 27 | succ_rsp - pointer to the drb_setup_succ_rsp_info to populate 28 | if the drb setup was successful 29 | fail_rsp - pointer to the drb_setup_fail_rsp_info to populate in case 30 | drb setup failed 31 | 32 | @returns 33 | 34 | pfm_retval_t - PFM_TRUE - if drb_entry creation was 35 | successful, rsp will be set 36 | 37 | PFM_FALSE - if drb_entry creation was 38 | unsuccessful, rsp will not 39 | be set and fail_rsp must 40 | be set by caller 41 | ***********************/ 42 | pfm_retval_t 43 | drb_setup(ue_ctx_t* ue_ctx, 44 | drb_setup_req_info_t* req, 45 | drb_setup_succ_rsp_info_t* succ_rsp, 46 | drb_setup_fail_rsp_info_t* fail_rsp); 47 | 48 | /********************** 49 | 50 | drb_setup_fail_rsp_create 51 | 52 | Create drb_setup_fail_rsp_info if creation of tunnel entry was unsuccessful 53 | 54 | @params 55 | 56 | req - pointer to drb_setup_req_info that failed drb_create 57 | fail_rsp - pointer to drb_setup_fail_rsp_info that corresponds to 58 | req 59 | cause - The cause for drb_setup failure 60 | 61 | @returns 62 | void 63 | 64 | **********************/ 65 | 66 | void 67 | drb_setup_fail_rsp_create(drb_setup_req_info_t* req, 68 | drb_setup_fail_rsp_info_t *fail_rsp, 69 | e1ap_fail_cause_t cause); 70 | 71 | /************************ 72 | drb_modify 73 | 74 | To modify an existing pdus entry with given drb_setup_req_info and position in 75 | drb_tunnel_list to modify the entry and reassign to list and create it's 76 | responses fail or success depending on result, the drb in the requests are 77 | modified and reassigned but not commited 78 | @params 79 | 80 | ue_ctx - pointer to the ue_ctx to populate 81 | req - pointer to the drb_modify_req_info to create drb_entry 82 | succ_rsp - pointer to the drb_modify_succ_rsp_info to populate 83 | if the drb modification was successful 84 | fail_rsp - pointer to the drb_modify_fail_rsp_info to populate if 85 | the drb modification was unsuccessful 86 | id_x - the index of the entry to be modified in drb_tunnel_list 87 | 88 | @returns 89 | 90 | pfm_retval_t - PFM_TRUE - if drb_entry creation was 91 | successful, rsp will be set 92 | 93 | PFM_FALSE - if drb_entry creation was 94 | unsuccessful, rsp will not 95 | be set and fail_rsp must 96 | be set by caller 97 | **************************/ 98 | 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/e1ap_bearer_setup.c: -------------------------------------------------------------------------------- 1 | #include "pfm.h" 2 | #include "pfm_log.h" 3 | #include "pfm_utils.h" 4 | #include "cuup.h" 5 | #include "e1ap_bearer_setup.h" 6 | #include "e1ap_comm.h" 7 | #include "tunnel.h" 8 | #include "ue_ctx.h" 9 | #include "pdus.h" 10 | #include "drb.h" 11 | 12 | 13 | 14 | // Assuming that if things go wrong before even an id is allocated the 15 | // the cuup_ue_id is set as 0 for the failure response 16 | static void 17 | e1ap_bearer_setup_fail(uint32_t cucp_ue_id, 18 | uint32_t cuup_ue_id, 19 | e1ap_fail_cause_t cause, 20 | e1ap_bearer_ctx_setup_rsp_t *rsp) 21 | { 22 | pfm_log_msg(PFM_LOG_ERR,"bearer setup failure"); 23 | rsp->cuup_ue_id = cuup_ue_id; 24 | rsp->cucp_ue_id = cucp_ue_id; 25 | rsp->cause = cause; 26 | rsp->pdus_setup_succ_count = 0; 27 | return; 28 | } 29 | 30 | 31 | pfm_retval_t 32 | e1ap_bearer_ctx_setup(e1ap_bearer_ctx_setup_req_t *req, 33 | e1ap_bearer_ctx_setup_rsp_t *rsp) 34 | { 35 | int i; 36 | pfm_retval_t ret; 37 | ue_ctx_t *ue_ctx; 38 | uint32_t ue_id; 39 | char ip_str[STR_IP_ADDR_SIZE]; 40 | // Allocate a ue_id 41 | ret = ue_ctx_id_alloc(&ue_id); 42 | if (ret == PFM_FAILED) 43 | { 44 | pfm_log_msg(PFM_LOG_ERR,"Error allocating ue_id"); 45 | e1ap_bearer_setup_fail(req->cucp_ue_id,MAX_UE_COUNT,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL,rsp); 46 | return PFM_FAILED; 47 | } 48 | 49 | // Allocate an empty ue_ctx entry 50 | ue_ctx = ue_ctx_add(ue_id); 51 | if (ue_ctx == NULL) 52 | { 53 | pfm_log_msg(PFM_LOG_ERR,"Error allocating ue_ctx"); 54 | ue_ctx_id_free(&ue_id); 55 | e1ap_bearer_setup_fail(req->cucp_ue_id,MAX_UE_COUNT,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL,rsp); 56 | return PFM_FAILED; 57 | } 58 | 59 | // Fill up the basic ue details 60 | ue_ctx->cucp_ue_id = req->cucp_ue_id; 61 | ue_ctx->pdus_count = 0; 62 | ue_ctx->drb_count = 0; 63 | ue_ctx->new_ul_flow_detected_count = 0; 64 | 65 | // Setup the rsp values we currently know 66 | rsp->cuup_ue_id = ue_ctx->cuup_ue_id; 67 | rsp->cucp_ue_id = ue_ctx->cucp_ue_id; 68 | // Cause is 0 for success 69 | rsp->cause = 0; 70 | rsp->pdus_setup_succ_count = 0; 71 | rsp->pdus_setup_fail_count = 0; 72 | 73 | 74 | // Service each pdus_create_request 75 | for (i = 0;i < req->pdus_count;i++) 76 | { 77 | // Storing pointers to make stuff easier 78 | pdus_setup_succ_rsp_info_t* succ_rsp = 79 | &(rsp->pdus_succ_list[rsp->pdus_setup_succ_count]); 80 | pdus_setup_fail_rsp_info_t* fail_rsp = 81 | &(rsp->pdus_fail_list[rsp->pdus_setup_fail_count]); 82 | 83 | // service each pdus request 84 | ret = pdus_setup(ue_ctx,&(req->pdus_list[i]),succ_rsp,fail_rsp); 85 | // If failed make failed rsp 86 | if (ret == PFM_FAILED) 87 | { 88 | pfm_log_msg(PFM_LOG_ERR,"Error creating PDUS entry" 89 | "pdus_id : %u remote-ip : %s" 90 | " remote-te-id : %u", 91 | req->pdus_list[i].pdus_id, 92 | pfm_ip2str(req->pdus_list[i].pdus_ul_ip_addr,ip_str), 93 | req->pdus_list[i].pdus_ul_teid); 94 | rsp->pdus_setup_fail_count++; 95 | continue; 96 | } 97 | rsp->pdus_setup_succ_count++; 98 | } 99 | // If all pdus_reqs failed 100 | 101 | if (rsp->pdus_setup_succ_count == 0) 102 | { 103 | pfm_log_msg(PFM_LOG_ERR,"all pdus requests failed ue_id %d", 104 | ue_id); 105 | ue_ctx_remove(ue_id); 106 | ue_ctx_commit(ue_ctx); 107 | e1ap_bearer_setup_fail(req->cucp_ue_id,ue_ctx->cucp_ue_id,FAIL_CAUSE_RNL_UNSPECIFIED,rsp); 108 | return PFM_FAILED; 109 | } 110 | ret = ue_ctx_commit(ue_ctx); 111 | if (ret == PFM_FAILED) 112 | { 113 | pfm_log_msg(PFM_LOG_ERR,"Error committing ue_ctx ue_id %d", 114 | ue_id); 115 | ue_ctx_remove(ue_id); 116 | ue_ctx_commit(ue_ctx); 117 | e1ap_bearer_setup_fail(req->cucp_ue_id,ue_id,FAIL_CAUSE_RNL_UNSPECIFIED,rsp); 118 | } 119 | return ret; 120 | } 121 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/e1ap_bearer_setup.h: -------------------------------------------------------------------------------- 1 | #ifndef __E1AP_BEARER_SETUP_H__ 2 | #define __E1AP_BEARER_SETUP_H__ 1 3 | 4 | #include "cuup.h" 5 | #include "e1ap_comm.h" 6 | 7 | // BEARER CONTEXT SETUP REQUEST Sec 9.2.2.1 of 3GPP TS 38.463 8 | typedef struct 9 | { 10 | uint32_t cucp_ue_id; 11 | 12 | // PDU Session Resource To Setup List 9.3.3.2 13 | uint8_t pdus_count; 14 | pdus_setup_req_info_t pdus_list[MAX_PDUS_PER_UE]; 15 | } e1ap_bearer_ctx_setup_req_t; 16 | 17 | // BEARER CONTEXT SETUP RESPONSE. sec 9.2.2.2 of 3GPP TS 38.463 18 | typedef struct 19 | { 20 | uint32_t cucp_ue_id; 21 | uint32_t cuup_ue_id; 22 | e1ap_fail_cause_t cause; // set to 0 is sucess 23 | uint8_t pdus_setup_succ_count; 24 | uint8_t pdus_setup_fail_count; 25 | pdus_setup_succ_rsp_info_t pdus_succ_list[MAX_PDUS_PER_UE]; 26 | pdus_setup_fail_rsp_info_t pdus_fail_list[MAX_PDUS_PER_UE]; 27 | } e1ap_bearer_ctx_setup_rsp_t; 28 | 29 | 30 | pfm_retval_t 31 | e1ap_bearer_ctx_setup(e1ap_bearer_ctx_setup_req_t *req,e1ap_bearer_ctx_setup_rsp_t *rsp); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/ipcmd.txt: -------------------------------------------------------------------------------- 1 | 2 | ip [ OPTIONS ] OBJECT { COMMAND | help } 3 | 4 | where 5 | 6 | OBJECT = link(l), address(a), route(r), neigh(n), rule(ru) 7 | 8 | 9 | use 'ip OBJECT help' the get options 10 | 11 | 1. Show IP address of eth0 12 | 13 | ip addr show dev eth0 14 | 15 | 2. Assigne IP address to eth0 16 | 17 | ip addr add 192.168.121.45/24 dev eth0 18 | 19 | 3. Remove IP Address from eth0 20 | 21 | ip addr add 192.168.121.45/24 dev eth0 22 | 23 | 4. Bring eth0 interface up 24 | 25 | ip link set eth0 up 26 | 27 | 5. Dispay route 28 | 29 | ip route list 30 | 31 | 6. Dispaly route of a specific network 32 | 33 | ip r list 172.17.0.0/16 34 | 35 | 7. Add new route 36 | 37 | ip r add 172.17.0.0/16 dev eth0 38 | 39 | 8. Add default route 40 | 41 | ip r add default via 192.168.121.1 dev eth0 42 | 43 | 9. Delete route 44 | 45 | ip route del default 46 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/pdus.c: -------------------------------------------------------------------------------- 1 | #include "pfm.h" 2 | #include "pfm_comm.h" 3 | #include "pfm_log.h" 4 | #include "cuup.h" 5 | #include "tunnel.h" 6 | #include "ue_ctx.h" 7 | #include "pdus.h" 8 | #include "drb.h" 9 | #include "e1ap_comm.h" 10 | #include "e1ap_bearer_setup.h" 11 | static void 12 | pdus_setup_succ_rsp_create(tunnel_t *tunnel_entry,pdus_setup_succ_rsp_info_t *succ_rsp) 13 | { 14 | succ_rsp->pdus_id = tunnel_entry->pdus_info.pdus_id; 15 | succ_rsp->drb_setup_succ_count = 0; 16 | succ_rsp->drb_setup_fail_count = 0; 17 | succ_rsp->pdus_dl_ip_addr = tunnel_entry->key.ip_addr; 18 | succ_rsp->pdus_dl_teid = tunnel_entry->key.te_id; 19 | return; 20 | } 21 | 22 | void 23 | pdus_setup_fail_rsp_create(pdus_setup_req_info_t* req, 24 | pdus_setup_fail_rsp_info_t* fail_rsp, 25 | e1ap_fail_cause_t cause) 26 | { 27 | fail_rsp->pdus_id = req->pdus_id; 28 | // TD how to assign cause 29 | fail_rsp->cause = cause; 30 | return; 31 | } 32 | 33 | 34 | pfm_retval_t 35 | pdus_setup(ue_ctx_t* ue_ctx, 36 | pdus_setup_req_info_t* req, 37 | pdus_setup_succ_rsp_info_t *succ_rsp, 38 | pdus_setup_fail_rsp_info_t *fail_rsp) 39 | { 40 | pfm_retval_t ret; 41 | tunnel_key_t tunnel_key; 42 | tunnel_t *tunnel_entry; 43 | 44 | drb_setup_succ_rsp_info_t* drb_succ_rsp; 45 | drb_setup_fail_rsp_info_t* drb_fail_rsp; 46 | 47 | // Assign a tunnel key with pdus_ul_ip_addr 48 | ret = tunnel_key_alloc(req->pdus_ul_ip_addr,TUNNEL_TYPE_PDUS,&tunnel_key); 49 | if (ret == PFM_FAILED) 50 | { 51 | pfm_log_msg(PFM_LOG_ERR,"Error allocating tunnel_key"); 52 | // TD assign cause properly 53 | pdus_setup_fail_rsp_create(req,fail_rsp,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL); 54 | return PFM_FAILED; 55 | } 56 | 57 | // Allocate a free entry from the tunnel table 58 | 59 | tunnel_entry = tunnel_add(&tunnel_key); 60 | if (tunnel_entry == NULL) 61 | { 62 | pfm_log_msg(PFM_LOG_ERR,"Error allocating tunnel_entry"); 63 | // TD assign cause properly 64 | tunnel_key_free(&tunnel_key); 65 | pdus_setup_fail_rsp_create(req,fail_rsp,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL); 66 | return PFM_FAILED; 67 | } 68 | 69 | // Fill in the pdus details to the entry 70 | tunnel_entry->remote_ip = req->pdus_ul_ip_addr; 71 | tunnel_entry->remote_te_id = req->pdus_ul_teid; 72 | tunnel_entry->tunnel_type = TUNNEL_TYPE_PDUS; 73 | tunnel_entry->pdus_info.pdus_id = req->pdus_id; 74 | 75 | // Setup up the succ_rsp since it's gone fine so far 76 | // Rest of the info is added as the drb's are processed 77 | 78 | pdus_setup_succ_rsp_create(tunnel_entry,succ_rsp); 79 | 80 | for (int i = 0;i < req->drb_count;i++) { 81 | // Storing frequently used pointers to make the variable names smaller 82 | drb_succ_rsp = &(succ_rsp->drb_succ_list[succ_rsp->drb_setup_succ_count]); 83 | drb_fail_rsp = &(succ_rsp->drb_fail_list[succ_rsp->drb_setup_fail_count]); 84 | 85 | // Process this drb 86 | ret = drb_setup(ue_ctx,&(req->drb_list[i]),drb_succ_rsp,drb_fail_rsp); 87 | 88 | // If failed log and increment the drb_setup_fail_count 89 | if (ret == PFM_FAILED){ 90 | pfm_log_msg(PFM_LOG_ERR,"Error creating DRB entry"); 91 | succ_rsp->drb_setup_fail_count++; 92 | continue; 93 | } 94 | succ_rsp->drb_setup_succ_count++; 95 | } 96 | // If all drb requests fail consider the pdu request a fail 97 | if (succ_rsp->drb_setup_fail_count == req->drb_count) 98 | { 99 | pfm_log_msg(PFM_LOG_ERR, 100 | "all drb_req in pdus_req failed pdus id :: %s:", 101 | req->pdus_id); 102 | tunnel_remove(&tunnel_key); 103 | tunnel_commit(tunnel_entry); 104 | 105 | pdus_setup_fail_rsp_create(req,fail_rsp,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL); 106 | return PFM_FAILED; 107 | } 108 | 109 | // Assign tunnel_entry to the next vacant spot 110 | ue_ctx->pdus_tunnel_list[ue_ctx->pdus_count] = tunnel_entry; 111 | ue_ctx->pdus_count++; 112 | return PFM_SUCCESS; 113 | } 114 | 115 | 116 | //---------------------------------------------------pdus_modify------------------------ 117 | 118 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/pdus.h: -------------------------------------------------------------------------------- 1 | #ifndef __PDUS_H__ 2 | #define __PDUS_H__ 3 | 4 | #include "tunnel.h" 5 | #include "ue_ctx.h" 6 | #include "e1ap_comm.h" 7 | #include "e1ap_bearer_setup.h" 8 | #include "cuup.h" 9 | #include "pfm_comm.h" 10 | #include "pfm.h" 11 | #include "cuup.h" 12 | 13 | /********************* 14 | 15 | pdus_setup 16 | 17 | Create a new pdus entry with given pdus_setup_req_info and create it's 18 | pdus_setup_succ_rsp_info if required. The entry if created successfully is 19 | assigned to the ue_ctx but not committed. The fail_rsp is also created calling 20 | pdus_setup_fail_rsp_create if failure occurred within pdus_setup if the failure 21 | to setup pdus occurred outside pdus_setup fail_rsp should be taken care of manually 22 | 23 | 24 | @params 25 | 26 | ue_ctx - pointer to the ue_ctx to populate 27 | req - pointer to the pdus_setup_req_info to create pdus_entry 28 | succ_rsp - pointer to the pdus_setup_succ_rsp_info to populate 29 | if the pdu setup was successful 30 | fail_rsp - pointer to the pdus_setup_succ_rsp_info to populate 31 | if pdu setup was unsuccessful 32 | 33 | @returns 34 | 35 | pfm_retval_t - PFM_TRUE - if pdus_entry creation was 36 | successful, rsp will be set 37 | 38 | PFM_FALSE - if pdus_entry creation was 39 | unsuccessful, rsp will not 40 | be set and fail_rsp must 41 | be set by caller 42 | ***********************/ 43 | pfm_retval_t 44 | pdus_setup(ue_ctx_t* ue_ctx, 45 | pdus_setup_req_info_t* req, 46 | pdus_setup_succ_rsp_info_t* succ_rsp, 47 | pdus_setup_fail_rsp_info_t* fail_rsp); 48 | 49 | /********************** 50 | 51 | pdus_setup_fail_rsp_create 52 | 53 | Create pdus_setup_fail_rsp_info if creation of tunnel entry was unsuccessful 54 | 55 | @params 56 | 57 | req - pointer to pdus_setup_req_info that failed pdus_create 58 | fail_rsp - pointer to pdus_setup_fail_rsp_info that corresponds to 59 | req 60 | cause - cause that caused failure of pdus_setup 61 | 62 | @returns 63 | void 64 | 65 | **********************/ 66 | 67 | void 68 | pdus_setup_fail_rsp_create(pdus_setup_req_info_t* req, 69 | pdus_setup_fail_rsp_info_t *fail_rsp, 70 | e1ap_fail_cause_t cause); 71 | 72 | /************************ 73 | pdus_modify 74 | 75 | To modify an existing pdus entry with given pdus_setup_req_info and positon in 76 | pdus_tunnel_list to modify the entry and reassign to list and create it's 77 | responses fail or success depending on result, the pdus and its associated drb in the 78 | request are modified but not committed 79 | 80 | @params 81 | 82 | ue_ctx - pointer to the ue_ctx to populate 83 | req - pointer to the pdus_modify_req_info to create pdus_entry 84 | succ_rsp - pointer to the pdus_modify_succ_rsp_info to populate 85 | if the pdus modification was successful 86 | fail_rsp - pointer to the pdus_modify_fail_rsp_info to populate if 87 | the pdus modification was unsuccessful 88 | id_x - the index of the entry to be modified in pdus_tunnel_list 89 | 90 | @returns 91 | 92 | pfm_retval_t - PFM_TRUE - if pdus_entry creation was 93 | successful, rsp will be set 94 | 95 | PFM_FALSE - if pdus_entry creation was 96 | unsuccessful, rsp will not 97 | be set and fail_rsp must 98 | be set by caller 99 | **************************/ 100 | 101 | #endif 102 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/pfm.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "pfm.h" 6 | #include "pfm_comm.h" 7 | 8 | pfm_retval_t pfm_init(int argc, char *argv[]) 9 | { 10 | int ret; 11 | int lcore_count; 12 | 13 | ret = rte_eal_init(argc, argv); 14 | if (0 > ret) 15 | { 16 | pfm_log_rte_err(PFM_LOG_EMERG, 17 | "rte_eal_init(argc=%d,argc=%p) failed. Terminating", 18 | argc, argv); 19 | return PFM_FAILED; 20 | } 21 | pfm_trace_msg("EAL Initialized"); 22 | 23 | lcore_count = rte_lcore_count(); 24 | pfm_trace_msg("Detected %d lcores",lcore_count); 25 | } 26 | 27 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/pfm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_H__ 2 | #define __PFM_H__ 1 3 | 4 | #include 5 | #include "pfm_log.h" 6 | 7 | typedef enum 8 | { 9 | PROTOCOL_UDP = 17 10 | } pfm_protocol_t; 11 | 12 | typedef uint32_t pfm_ip_addr_t; 13 | 14 | typedef enum 15 | { 16 | PFM_SUCCESS, 17 | PFM_FAILED, 18 | PFM_NOT_FOUND 19 | } pfm_retval_t; 20 | 21 | typedef enum 22 | { 23 | PFM_FALSE = 0, 24 | PFM_TRUE = 1 25 | } pfm_bool_t; 26 | 27 | pfm_retval_t pfm_init(int argc, char *argv[]); 28 | 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/pfm_comm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_COMM_H__ 2 | #define __PFM_COMM_H__ 1 3 | #include 4 | #include "pfm.h" 5 | #define MAX_LCORES 32 6 | #define MAX_LINK_COUNT 5 7 | #define LAST_LINK_ID MAX_LINK_COUNT 8 | #define MAX_KNI_PORTS 5 9 | #define MAX_LOCAL_IP_COUNT (MAX_KNI_PORTS*2) 10 | 11 | #define MBUF_COUNT 4096 12 | #define MBUF_CASHE_SIZE 128 13 | #define MBUF_PRIV_SIZE 0 14 | 15 | /* DPDK object names */ 16 | #define MBUF_NAME "MBUF" 17 | #define TX_RING_NAME "TXRING" 18 | #define RX_RING_NAME "RXRING" 19 | #define DIST_NAME "DISTNAME" 20 | 21 | #define TX_RING_SIZE 64 22 | #define RX_RING_SIZE TX_RING_SIZE 23 | #define TX_BURST_SIZE 32 24 | #define RX_BURST_SIZE TX_BURST_SIZE 25 | 26 | #define MAC_ADDR_SIZE RTE_ETHER_ADDR_LEN 27 | #define IP_ADDR_SIZE 4 28 | #define STR_IP_ADDR_SIZE 20 29 | #define DEFAULT_MTU_SIZE 1500 30 | #define DEFAULT_MIN_MTU_SIZE 68 31 | #define DEFAULT_MAX_MTU_SIZE 65535 32 | 33 | #define TIMER_RESOLUTION_CYCLES 20000000ULL 34 | 35 | #define ARP_TABLE_SIZE 32 36 | 37 | enum { 38 | LCORE_MAIN = 0, 39 | LCORE_RXLOOP = 1, 40 | LCORE_TXLOOP = 2, 41 | LCORE_DISTRIBUTOR = 3, 42 | LCORE_WORKER = 4, 43 | LCORE_MIN_LCORE_COUNT 44 | }; 45 | 46 | #define MAX_WORKERS (MAX_LCORES - LCORE_WORKER) 47 | typedef enum 48 | { 49 | ADMSTATE_UNLOCKED, 50 | ADMSTATE_LOCKED, 51 | } admin_state_t; 52 | 53 | typedef enum 54 | { 55 | OPSSTATE_NOTCONFIGURED, 56 | OPSSTATE_ENABLED, 57 | OPSSTATE_DISABLED, 58 | OPSSTATE_FAULTY 59 | } ops_state_t; 60 | 61 | typedef struct { 62 | int kniIdx; 63 | pfm_ip_addr_t ip_addr; 64 | pfm_ip_addr_t network_mask; 65 | pfm_ip_addr_t default_gateway_ip; 66 | } local_ip_addr_t; 67 | 68 | typedef struct { 69 | int lcore_count; 70 | int kni_count; 71 | int local_ip_count; 72 | local_ip_addr_t local_ip_addr_list[MAX_LOCAL_IP_COUNT]; 73 | struct rte_mempool *mbuf_pool; 74 | struct rte_ring *rx_ring_ptr ; 75 | struct rte_ring *tx_ring_ptr ; 76 | struct rte_kni *kni_ptr; 77 | struct rte_distributor *dist_ptr; 78 | } sys_info_t; 79 | 80 | 81 | extern volatile pfm_bool_t force_quit_g; /* all loops will use this 82 | varable to determin the looping need to continue 83 | or not. By setting this varlbale to TRUE, all loops 84 | can be terminated */ 85 | extern sys_info_t sys_info_g; 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/pfm_utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pfm.h" 7 | #include "pfm_comm.h" 8 | #include "pfm_log.h" 9 | #include "pfm_utils.h" 10 | 11 | pfm_ip_addr_t pfm_str2ip(const char *ip_str) 12 | { 13 | pfm_ip_addr_t ipn; // IP in network order 14 | pfm_ip_addr_t iph; // IP in host order 15 | int ret; 16 | 17 | ret = inet_pton(AF_INET,ip_str,&ipn); 18 | if (1 != ret) 19 | { 20 | pfm_log_std_err(PFM_LOG_WARNING, 21 | "Failed to convert IP=[%s] to " 22 | "pfm_ip_addr_t format", ip_str); 23 | return 0; 24 | } 25 | iph = ntohl(ipn); 26 | return iph; 27 | } 28 | 29 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_str) 30 | { 31 | pfm_ip_addr_t ipn; // IP in network order 32 | 33 | ipn = htonl(iph); 34 | const char *ret = inet_ntop(AF_INET,&ipn,ip_str,STR_IP_ADDR_SIZE); 35 | if (NULL == ret) 36 | { 37 | pfm_log_std_err(PFM_LOG_ERR, 38 | "Failed to IP=[0x%0X] to string format",iph); 39 | return NULL; 40 | } 41 | return ip_str; 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/pfm_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_UTILS_H__ 2 | #define __PFM_UTILS_H__ 1 3 | #include "pfm.h" 4 | 5 | pfm_ip_addr_t pfm_str2ip(const char *ip_str); 6 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_addr_str); 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/run.sh: -------------------------------------------------------------------------------- 1 | sudo ./build/cuup.exe --lcore '0@0,1@1,2@0,3@1,4@0,5@1' --syslog local6 2 | 3 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/tunnel.h: -------------------------------------------------------------------------------- 1 | #ifndef __TUNNEL_H__ 2 | #define __TUNNEL_H__ 1 3 | #include "pfm.h" 4 | #include "cuup.h" 5 | 6 | typedef enum 7 | { 8 | TUNNEL_TYPE_PDUS, 9 | TUNNEL_TYPE_DRB, 10 | } tunnel_type_t; 11 | 12 | typedef struct 13 | { 14 | unsigned int drb_id:5; 15 | unsigned int is_default:1; 16 | unsigned int is_dl_sdap_hdr_enabled:1; 17 | unsigned int is_ul_sdap_hdr_enabled:1; 18 | uint32_t mapped_flow_idx; // valid only if is_ul_sdap_hdr_enabled 19 | uint32_t mapped_pdus_idx; 20 | } drb_info_t; 21 | 22 | typedef struct 23 | { 24 | unsigned int flow_id:6; 25 | unsigned int r_qos_status:2; 26 | uint32_t mapped_drb_idx; 27 | } flow_info_t; 28 | 29 | typedef struct 30 | { 31 | unsigned int pdus_id:8; 32 | unsigned int flow_count:6; 33 | uint64_t ul_new_flow_detected_bit_map; 34 | flow_info_t flow_list[MAX_FLOWS_PER_PDUS]; 35 | } pdus_info_t; 36 | 37 | typedef struct 38 | { 39 | uint32_t ip_addr; 40 | uint32_t te_id; 41 | } tunnel_key_t; 42 | 43 | typedef struct 44 | { 45 | tunnel_key_t key; 46 | pfm_ip_addr_t remote_ip; 47 | uint32_t remote_te_id; 48 | tunnel_type_t tunnel_type:2; 49 | pfm_bool_t is_row_used:1; 50 | union 51 | { 52 | pdus_info_t pdus_info; 53 | drb_info_t drb_info; 54 | }; 55 | } tunnel_t; 56 | 57 | 58 | const tunnel_t* tunnel_get(tunnel_key_t *key); 59 | tunnel_t * tunnel_add(tunnel_key_t *key); 60 | pfm_retval_t tunnel_remove(tunnel_key_t *key); 61 | tunnel_t * tunnel_modify(tunnel_key_t *key); 62 | pfm_retval_t tunnel_commit(tunnel_t* nt); 63 | void tunnel_print_show(FILE *fp, tunnel_key_t *key); 64 | void tunnel_print_list(FILE *fp, tunnel_type_t ttype); 65 | pfm_retval_t tunnel_key_alloc(pfm_ip_addr_t ip,tunnel_type_t ttype,tunnel_key_t *key); 66 | pfm_retval_t tunnel_key_free(tunnel_key_t *tunnel_key); 67 | #endif 68 | -------------------------------------------------------------------------------- /criterion_tests/e1ap/e1ap_bearer_setup/ue_ctx.h: -------------------------------------------------------------------------------- 1 | #ifndef __UE_CTX_H__ 2 | #define __UE_CTX_H__ 1 3 | 4 | #include "tunnel.h" 5 | 6 | 7 | typedef struct 8 | { 9 | uint32_t cuup_ue_id; // 32 bit gNB-CU-UP UE E1AP ID 10 | uint32_t cucp_ue_id; // 32 bit gNB-CU-CP UE E1AP ID 11 | uint8_t pdus_count:8; // PDU Session count 12 | uint8_t drb_count:5; 13 | uint8_t new_ul_flow_detected_count:5; 14 | pfm_bool_t is_row_used:1; 15 | tunnel_t * pdus_tunnel_list[MAX_PDUS_PER_UE]; 16 | tunnel_t * drb_tunnel_list[MAX_DRB_PER_UE]; 17 | } ue_ctx_t; 18 | 19 | ue_ctx_t * ue_ctx_add(uint32_t ue_id); 20 | pfm_retval_t ue_ctx_remove(uint32_t ue_id); 21 | ue_ctx_t * ue_ctx_modify(uint32_t ue_id); 22 | pfm_retval_t ue_ctx_commit(ue_ctx_t *new_ctx); 23 | const ue_ctx_t * ue_ctx_get(uint32_t ue_id); 24 | void ue_ctx_print_list(FILE *fp); 25 | void ue_ctx_print_show(FILE *fp, uint32_t ue_id); 26 | pfm_retval_t ue_ctx_id_alloc(uint32_t *ue_id); 27 | pfm_retval_t ue_ctx_id_free(uint32_t *ue_id); 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /cuup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pfm.h" 7 | #include "pfm_comm.h" 8 | #include "pfm_utils.h" 9 | #include "pfm_cli.h" 10 | #include "pfm_route.h" 11 | 12 | #define GTP_PORTNO 2152 13 | 14 | static void terminate_program(void) 15 | { 16 | pfm_terminate(); 17 | pfm_log_close(); 18 | return; 19 | } 20 | 21 | static void signal_handler(int sig_num) 22 | { 23 | if ( ( SIGINT == sig_num ) || 24 | ( SIGTERM == sig_num )) 25 | { 26 | pfm_trace_msg("Signal %d received, preparing to exit..", 27 | sig_num); 28 | terminate_program(); 29 | } 30 | return; 31 | } 32 | 33 | 34 | int main(int argc, char *argv[]) 35 | { 36 | pfm_retval_t ret_val; 37 | pfm_cli_retval_t cli_ret_val; 38 | int ret; 39 | int lcore_id; 40 | 41 | /* initialize logging and tracing libs*/ 42 | pfm_log_open("CUUP",PFM_LOG_DEBUG); 43 | 44 | /* install signal handlers */ 45 | signal(SIGINT, signal_handler); 46 | signal(SIGTERM, signal_handler); 47 | 48 | ret_val = pfm_init(argc, argv); 49 | if (PFM_SUCCESS != ret_val) 50 | { 51 | terminate_program(); 52 | exit(1); 53 | } 54 | 55 | pfm_link_open("0000:00:09.0"); 56 | pfm_link_open("0000:00:0a.0"); 57 | 58 | pfm_ip_addr_t ip; 59 | 60 | ip = pfm_str2ip("192.168.57.200"); 61 | ret_val = pfm_ingress_classifier_add(0,"NGu0",ip,24,GTP_PORTNO); 62 | 63 | ip = pfm_str2ip("192.168.57.201"); 64 | ret_val = pfm_ingress_classifier_add(0,"NGu1",ip,24,GTP_PORTNO); 65 | 66 | 67 | ip = pfm_str2ip("192.168.58.202"); 68 | ret_val = pfm_ingress_classifier_add(1,"F1u0",ip,24,GTP_PORTNO); 69 | 70 | ip = pfm_str2ip("192.168.58.203"); 71 | ret_val = pfm_ingress_classifier_add(1,"F1u1",ip,24,GTP_PORTNO); 72 | 73 | if (PFM_SUCCESS != ret_val) 74 | { 75 | pfm_log_msg(PFM_LOG_WARNING, 76 | "KNI Port creation failed"); 77 | exit(3); 78 | } 79 | 80 | ret_val = pfm_start_pkt_processing(); 81 | if (PFM_SUCCESS != ret_val) 82 | { 83 | pfm_log_msg(PFM_LOG_WARNING, 84 | "pfm_start_pkt_processing() failed"); 85 | terminate_program(); 86 | exit(2); 87 | } 88 | 89 | pfm_cli_init(); 90 | 91 | cli_ret_val = PFM_CLI_CONTINUE; 92 | while((PFM_CLI_EXIT != cli_ret_val) && 93 | (PFM_CLI_SHUTDOWN != cli_ret_val)) 94 | { 95 | cli_ret_val = pfm_cli_exec(stdin,stdout); 96 | }; 97 | 98 | 99 | RTE_LCORE_FOREACH_SLAVE(lcore_id) 100 | { 101 | ret = rte_eal_wait_lcore(lcore_id); 102 | if (0 != ret) 103 | { 104 | pfm_log_rte_err(PFM_LOG_WARNING, 105 | "rte_eal_wait_lcore(lcore=%d) failed", 106 | lcore_id); 107 | exit(3); 108 | } 109 | else 110 | { 111 | pfm_trace_msg("lcore %d stopped", lcore_id); 112 | } 113 | } 114 | pfm_trace_msg("All slave threads stopped"); 115 | 116 | terminate_program(); 117 | exit(0); 118 | } 119 | 120 | /************* 121 | * 122 | * pfm_data_ind() 123 | * 124 | * When PFM wants to pass a packet to application, it invokes this function. 125 | * This is a dummy function which need to be implemented by application 126 | * It needs to be replaced when application is implemented. 127 | * 128 | * 129 | ****************/ 130 | 131 | /* 132 | void pfm_data_ind( const pfm_ip_addr_t remote_ip_addr, 133 | const pfm_ip_addr_t local_ip_addr, 134 | pfm_protocol_t protocol, 135 | const int remote_port_no, 136 | const int local_port_no, 137 | struct rte_mbuf *mbuf) 138 | { 139 | unsigned char *pkt; 140 | int pkt_len; 141 | 142 | char local_ip_addr_str[STR_IP_ADDR_SIZE]; 143 | char remote_ip_addr_str[STR_IP_ADDR_SIZE]; 144 | 145 | printf("Invoked pfm_data_ind(remote_ip=%s,local_ip=%s," 146 | "protocol=%d," 147 | "remote_port=%d,local_port=%d,buffer pointer=%p\n", 148 | pfm_ip2str(remote_ip_addr,remote_ip_addr_str), 149 | pfm_ip2str(local_ip_addr,local_ip_addr_str), 150 | protocol, 151 | remote_port_no, 152 | local_port_no, 153 | mbuf); 154 | 155 | pkt = rte_pktmbuf_mtod(mbuf,unsigned char*); 156 | pkt_len = mbuf->pkt_len; 157 | pfm_trace_pkt_hdr(pkt,pkt_len,"Rx on worker [%d]",rte_lcore_id()); 158 | pfm_trace_pkt(pkt,pkt_len,"Rx on worker [%d]",rte_lcore_id()); 159 | 160 | pfm_data_req( local_ip_addr, remote_ip_addr, 161 | protocol, 162 | local_port_no,remote_port_no, 163 | mbuf); 164 | 165 | return; 166 | } 167 | 168 | 169 | */ 170 | -------------------------------------------------------------------------------- /cuup.h: -------------------------------------------------------------------------------- 1 | #ifndef __CUUP_H__ 2 | #define __CUUP_H__ 1 3 | 4 | #define MAX_DU_COUNT 20 // TODO what number to put 5 | #define MAX_UPF_COUNT 20 // 6 | #define MAX_UE_COUNT 1000 7 | #define MAX_PDUS_PER_UE 4 // range 1 to 256 8 | #define MAX_DRB_PER_PDUS 4 // range 1 to 32 9 | #define MAX_FLOWS_PER_PDUS 4 // rnage 1 to 32 10 | #define MAX_DRB_PER_UE MAX_DRB_PER_PDUS // range 1 to 32 11 | 12 | 13 | #define MAX_TUNNEL_COUNT (MAX_UE_COUNT * MAX_PDUS_PER_UE * MAX_DRB_PER_UE) 14 | 15 | #define NEW_UL_FLOW_NOTIFY_TIMEOUT 100 // in msec 16 | #define NEW_UL_FLOW_NOTIFY_BUNDLE_SIZE 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /drb.h: -------------------------------------------------------------------------------- 1 | #ifndef __DRB_H__ 2 | #define __DRB_H__ 3 | 4 | 5 | #include "tunnel.h" 6 | #include "ue_ctx.h" 7 | #include "e1ap_comm.h" 8 | #include "e1ap_bearer_modify.h" 9 | #include "cuup.h" 10 | #include "pfm_comm.h" 11 | #include "pfm.h" 12 | #include "cuup.h" 13 | 14 | /********************* 15 | 16 | drb_setup 17 | 18 | Create a new drb entry with given drb_setup_req_info and create it's 19 | drb_setup_succ_rsp_info if required. The entry if created successfully is 20 | assigned to the ue_ctx but not committed.If entry creation failed creation of 21 | failure response must be handled by caller. 22 | 23 | @params 24 | 25 | ue_ctx - pointer to the ue_ctx to populate 26 | req - pointer to the drb_setup_req_info to create drb_entry 27 | succ_rsp - pointer to the drb_setup_succ_rsp_info to populate 28 | if the drb setup was successful 29 | fail_rsp - pointer to the drb_setup_fail_rsp_info to populate in case 30 | drb setup failed 31 | 32 | @returns 33 | 34 | pfm_retval_t - PFM_TRUE - if drb_entry creation was 35 | successful, rsp will be set 36 | 37 | PFM_FALSE - if drb_entry creation was 38 | unsuccessful, rsp will not 39 | be set and fail_rsp must 40 | be set by caller 41 | ***********************/ 42 | pfm_retval_t 43 | drb_setup(ue_ctx_t* ue_ctx, 44 | drb_setup_req_info_t* req, 45 | drb_setup_succ_rsp_info_t* succ_rsp, 46 | drb_setup_fail_rsp_info_t* fail_rsp); 47 | 48 | /********************** 49 | 50 | drb_setup_fail_rsp_create 51 | 52 | Create drb_setup_fail_rsp_info if creation of tunnel entry was unsuccessful 53 | 54 | @params 55 | 56 | req - pointer to drb_setup_req_info that failed drb_create 57 | fail_rsp - pointer to drb_setup_fail_rsp_info that corresponds to 58 | req 59 | cause - The cause for drb_setup failure 60 | 61 | @returns 62 | void 63 | 64 | **********************/ 65 | 66 | void 67 | drb_setup_fail_rsp_create(drb_setup_req_info_t* req, 68 | drb_setup_fail_rsp_info_t *fail_rsp, 69 | e1ap_fail_cause_t cause); 70 | 71 | /************************ 72 | drb_modify 73 | 74 | To modify an existing pdus entry with given drb_setup_req_info and position in 75 | drb_tunnel_list to modify the entry and reassign to list and create it's 76 | responses fail or success depending on result, the drb in the requests are 77 | modified and reassigned but not commited 78 | @params 79 | 80 | ue_ctx - pointer to the ue_ctx to populate 81 | req - pointer to the drb_modify_req_info to create drb_entry 82 | succ_rsp - pointer to the drb_modify_succ_rsp_info to populate 83 | if the drb modification was successful 84 | fail_rsp - pointer to the drb_modify_fail_rsp_info to populate if 85 | the drb modification was unsuccessful 86 | id_x - the index of the entry to be modified in drb_tunnel_list 87 | 88 | @returns 89 | 90 | pfm_retval_t - PFM_TRUE - if drb_entry creation was 91 | successful, rsp will be set 92 | 93 | PFM_FALSE - if drb_entry creation was 94 | unsuccessful, rsp will not 95 | be set and fail_rsp must 96 | be set by caller 97 | **************************/ 98 | 99 | pfm_retval_t 100 | drb_modify(ue_ctx_t* ue_ctx, 101 | drb_modify_req_info_t *req, 102 | drb_setup_succ_rsp_info_t *succ_rsp, 103 | drb_setup_fail_rsp_info_t *fail_rsp, 104 | uint32_t idx); 105 | 106 | 107 | /*************************** 108 | 109 | drb_modify_fail_rsp_create 110 | 111 | create the failure response in case drb_modify fails filling in the required info 112 | into the provided drb_modify_fail_rsp_info pointer 113 | 114 | @params 115 | 116 | req - pointer to the modify request that failed 117 | fail_rsp - pointer to the fail response 118 | cause - reason for failure 119 | 120 | @returns 121 | 122 | void 123 | 124 | ****************************/ 125 | void 126 | drb_modify_fail_rsp_create(drb_modify_req_info_t *req, 127 | drb_setup_fail_rsp_info_t *rsp, 128 | e1ap_fail_cause_t cause); 129 | 130 | pfm_retval_t drb_remove(tunnel_key_t *tunnel_key); 131 | 132 | pfm_retval_t drb_commit(tunnel_t *nt); 133 | 134 | pfm_retval_t drb_rollback(tunnel_t *nt); 135 | #endif 136 | -------------------------------------------------------------------------------- /e1ap_bearer_modify.h: -------------------------------------------------------------------------------- 1 | #ifndef __E1AP_BEARER_MODIFY_H__ 2 | #define __E1AP_BEARER_MODIFY_H__ 1 3 | 4 | #include "cuup.h" 5 | #include "e1ap_comm.h" 6 | 7 | typedef pdus_setup_fail_rsp_info_t pdus_modify_fail_rsp_info_t; 8 | 9 | // BEARER CONTEXT MODIFICATION REQUEST sec 9.2.2.4 of 3GPP TS 38.463 10 | // PDU Session Resource to Modify List 9.3.3.11 11 | // DRB To Modify List 12 | typedef struct 13 | { 14 | uint8_t drb_id; 15 | } drb_modify_req_info_t; 16 | 17 | 18 | // BEARER CONTEXT MODIFICATION REQUEST sec 9.2.2.4 of 3GPP TS 38.463 19 | // PDU Session Resource to Modify List 9.3.3.11 20 | // DRB To Remove List 21 | typedef struct 22 | { 23 | uint8_t drb_id; 24 | } drb_remove_req_info_t; 25 | 26 | // BEARER CONTEXT MODIFICATION REQUEST sec 9.2.2.4 of 3GPP TS 38.463 27 | // PDU Session Resource to Modify List 9.3.3.11 28 | typedef struct 29 | { 30 | uint8_t pdus_id; 31 | 32 | uint8_t drb_setup_count; 33 | uint8_t drb_modify_count; 34 | uint8_t drb_remove_count; 35 | drb_setup_req_info_t drb_setup_list[MAX_DRB_PER_PDUS]; 36 | drb_modify_req_info_t drb_modify_list[MAX_DRB_PER_PDUS]; 37 | drb_remove_req_info_t drb_remove_list[MAX_DRB_PER_PDUS]; 38 | } pdus_modify_req_info_t; 39 | 40 | // BEARER CONTEXT MODIFICATION REQUEST sec 9.2.2.4 of 3GPP TS 38.463 41 | // PDU Session Resource to Remove List 9.3.3.12 42 | typedef struct 43 | { 44 | uint8_t pdus_id; 45 | e1ap_fail_cause_t cause; 46 | } pdus_remove_req_info_t; 47 | 48 | 49 | // BEARER CONTEXT MODIFICATION RESPONSE. sec 9.2.2.5 50 | // PDU Session Resource Modify List 9.3.3.19 51 | typedef struct 52 | { 53 | uint8_t pdus_id; // PDU Session ID 9.3.1.21 54 | uint8_t drb_setup_succ_count; 55 | uint8_t drb_setup_fail_count; 56 | uint8_t drb_modify_succ_count; 57 | uint8_t drb_modify_fail_count; 58 | 59 | // NG DL UP Transport Layer Info 9.3.2.1 60 | // IP Address and TEID of CUUP to which UPF can send DL packets 61 | pfm_ip_addr_t pdus_dl_ip_addr; 62 | uint32_t pdus_dl_teid; 63 | 64 | // DRB Setup List 65 | drb_setup_succ_rsp_info_t drb_setup_succ_list[MAX_DRB_PER_PDUS]; 66 | 67 | // DRB Failed List 68 | drb_setup_fail_rsp_info_t drb_setup_fail_list[MAX_DRB_PER_PDUS]; 69 | 70 | // DRB Modification List 71 | drb_setup_succ_rsp_info_t drb_modify_succ_list[MAX_DRB_PER_PDUS]; 72 | 73 | // DRB Failed To Modify List 74 | drb_setup_fail_rsp_info_t drb_modify_fail_list[MAX_DRB_PER_PDUS]; 75 | 76 | } pdus_modify_succ_rsp_info_t; 77 | 78 | // BEARER CONTEXT MODIFICATION REQUEST sec 9.2.2.4 of 3GPP TS 38.463 79 | typedef struct 80 | { 81 | uint32_t cucp_ue_id; 82 | uint32_t cuup_ue_id; 83 | uint8_t pdus_setup_count; 84 | uint8_t pdus_modify_count; 85 | uint8_t pdus_remove_count; 86 | 87 | // PDU Session Resource to Setup List 9.3.3.10 88 | pdus_setup_req_info_t pdus_setup_list[MAX_PDUS_PER_UE]; 89 | 90 | // PDU Session Resource to Modify List 9.3.3.11 91 | pdus_modify_req_info_t pdus_modify_list[MAX_PDUS_PER_UE]; 92 | 93 | // PDU Session Resource to Remove List 9.3.3.12 94 | pdus_remove_req_info_t pdus_remove_list[MAX_PDUS_PER_UE]; 95 | 96 | } e1ap_bearer_ctx_modify_req_t; 97 | 98 | 99 | // BEARER CONTEXT MODIFICATION RESPONSE. sec 9.2.2.5 of 3GPP TS 38.463 100 | // BEARER CONTEXT MODIFICATION FAILURE sec 9.2.2.6 of 3GPP TS 38.463 101 | typedef struct 102 | { 103 | uint32_t cucp_ue_id; 104 | uint32_t cuup_ue_id; 105 | e1ap_fail_cause_t cause; // set to 0 is success 106 | uint8_t pdus_setup_succ_count; 107 | uint8_t pdus_setup_fail_count; 108 | uint8_t pdus_modify_succ_count; 109 | uint8_t pdus_modify_fail_count; 110 | 111 | // PDU Session Resource Setup List 9.3.3.17 112 | pdus_setup_succ_rsp_info_t pdus_setup_succ_list[MAX_PDUS_PER_UE]; 113 | 114 | // PDU Session Resource Failed List 9.3.3.18 115 | pdus_setup_fail_rsp_info_t pdus_setup_fail_list[MAX_PDUS_PER_UE]; 116 | 117 | // PDU Session Resource Modify List 9.3.3.19 118 | pdus_modify_succ_rsp_info_t pdus_modify_succ_list[MAX_PDUS_PER_UE]; 119 | 120 | // PDU Session Resource Failed To Modify List 9.3.3.20 121 | pdus_modify_fail_rsp_info_t pdus_modify_fail_list[MAX_PDUS_PER_UE]; 122 | 123 | } e1ap_bearer_ctx_modify_rsp_t; 124 | 125 | 126 | pfm_retval_t e1ap_bearer_ctx_modify( 127 | e1ap_bearer_ctx_modify_req_t *req, 128 | e1ap_bearer_ctx_modify_rsp_t *rsp); 129 | 130 | #endif 131 | -------------------------------------------------------------------------------- /e1ap_bearer_release.c: -------------------------------------------------------------------------------- 1 | #include "pfm.h" 2 | #include "pfm_utils.h" 3 | #include "pfm_comm.h" 4 | #include "cuup.h" 5 | #include "e1ap_bearer_release.h" 6 | #include "e1ap_comm.h" 7 | #include "ue_ctx.h" 8 | #include "tunnel.h" 9 | 10 | pfm_retval_t e1ap_bearer_ctx_release( e1ap_bearer_ctx_release_cmd_t *req) 11 | { 12 | pfm_retval_t ret; 13 | const ue_ctx_t* entry; 14 | 15 | ret = ue_ctx_remove(req->cuup_ue_id); 16 | if (ret != PFM_SUCCESS) 17 | { 18 | pfm_log_msg(PFM_LOG_ERR,"Error ue_ctx_remove failed %u", 19 | req->cuup_ue_id); 20 | return PFM_FAILED; 21 | } 22 | entry = ue_ctx_get(req->cuup_ue_id); 23 | ret = ue_ctx_commit(entry); 24 | if (ret != PFM_SUCCESS) 25 | { 26 | pfm_log_msg(PFM_LOG_ERR,"Error ue_ctx_commit failed %u", 27 | req->cuup_ue_id); 28 | return PFM_FAILED; 29 | } 30 | pfm_trace_msg("released UE id - %d",req->cuup_ue_id); 31 | return PFM_SUCCESS; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /e1ap_bearer_release.h: -------------------------------------------------------------------------------- 1 | #ifndef __E1AP_BEARER_RELESE__ 2 | #define __E1AP_BEARER_RELESE__ 1 3 | 4 | #include "cuup.h" 5 | #include "e1ap_comm.h" 6 | 7 | // BEARER CONTEXT RELEASE COMMAND 9.2.2.9 8 | typedef struct 9 | { 10 | uint32_t cuup_ue_id; 11 | } e1ap_bearer_ctx_release_cmd_t; 12 | 13 | pfm_retval_t e1ap_bearer_ctx_release( e1ap_bearer_ctx_release_cmd_t *req); 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /e1ap_bearer_setup.c: -------------------------------------------------------------------------------- 1 | #include "pfm.h" 2 | #include "pfm_log.h" 3 | #include "pfm_utils.h" 4 | #include "cuup.h" 5 | #include "e1ap_bearer_setup.h" 6 | #include "e1ap_comm.h" 7 | #include "tunnel.h" 8 | #include "ue_ctx.h" 9 | #include "pdus.h" 10 | #include "drb.h" 11 | 12 | 13 | 14 | // Assuming that if things go wrong before even an id is allocated the 15 | // the cuup_ue_id is set as 0 for the failure response 16 | static void 17 | e1ap_bearer_setup_fail(uint32_t cucp_ue_id, 18 | uint32_t cuup_ue_id, 19 | e1ap_fail_cause_t cause, 20 | e1ap_bearer_ctx_setup_rsp_t *rsp) 21 | { 22 | pfm_log_msg(PFM_LOG_ERR,"bearer setup failure"); 23 | rsp->cuup_ue_id = cuup_ue_id; 24 | rsp->cucp_ue_id = cucp_ue_id; 25 | rsp->cause = cause; 26 | rsp->pdus_setup_succ_count = 0; 27 | return; 28 | } 29 | 30 | 31 | pfm_retval_t 32 | e1ap_bearer_ctx_setup(e1ap_bearer_ctx_setup_req_t *req, 33 | e1ap_bearer_ctx_setup_rsp_t *rsp) 34 | { 35 | int i; 36 | pfm_retval_t ret; 37 | ue_ctx_t *ue_ctx; 38 | uint32_t ue_id; 39 | char ip_str[STR_IP_ADDR_SIZE]; 40 | // Allocate a ue_id 41 | ret = ue_ctx_id_alloc(&ue_id); 42 | if (ret == PFM_FAILED) 43 | { 44 | pfm_log_msg(PFM_LOG_ERR,"Error allocating ue_id"); 45 | e1ap_bearer_setup_fail(req->cucp_ue_id,MAX_UE_COUNT,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL,rsp); 46 | return PFM_FAILED; 47 | } 48 | 49 | // Allocate an empty ue_ctx entry 50 | ue_ctx = ue_ctx_add(ue_id); 51 | if (ue_ctx == NULL) 52 | { 53 | pfm_log_msg(PFM_LOG_ERR,"Error allocating ue_ctx"); 54 | e1ap_bearer_setup_fail(req->cucp_ue_id,MAX_UE_COUNT,FAIL_CAUSE_RNL_RESOURCE_UNAVAIL,rsp); 55 | return PFM_FAILED; 56 | } 57 | 58 | // Fill up the basic ue details 59 | ue_ctx->cucp_ue_id = req->cucp_ue_id; 60 | ue_ctx->pdus_count = 0; 61 | ue_ctx->drb_count = 0; 62 | ue_ctx->new_ul_flow_detected_count = 0; 63 | 64 | // Setup the rsp values we currently know 65 | rsp->cuup_ue_id = ue_ctx->cuup_ue_id; 66 | rsp->cucp_ue_id = ue_ctx->cucp_ue_id; 67 | // Cause is 0 for success 68 | rsp->cause = 0; 69 | rsp->pdus_setup_succ_count = 0; 70 | rsp->pdus_setup_fail_count = 0; 71 | 72 | 73 | // Service each pdus_create_request 74 | for (i = 0;i < req->pdus_count;i++) 75 | { 76 | // Storing pointers to make stuff easier 77 | pdus_setup_succ_rsp_info_t* succ_rsp = 78 | &(rsp->pdus_succ_list[rsp->pdus_setup_succ_count]); 79 | pdus_setup_fail_rsp_info_t* fail_rsp = 80 | &(rsp->pdus_fail_list[rsp->pdus_setup_fail_count]); 81 | 82 | // service each pdus request 83 | ret = pdus_setup(ue_ctx,&(req->pdus_list[i]),succ_rsp,fail_rsp); 84 | // If failed make failed rsp 85 | if (ret == PFM_FAILED) 86 | { 87 | pfm_log_msg(PFM_LOG_ERR,"Error creating PDUS entry" 88 | "pdus_id : %u remote-ip : %s" 89 | " remote-te-id : %u", 90 | req->pdus_list[i].pdus_id, 91 | pfm_ip2str(req->pdus_list[i].pdus_ul_ip_addr,ip_str), 92 | req->pdus_list[i].pdus_ul_teid); 93 | rsp->pdus_setup_fail_count++; 94 | continue; 95 | } 96 | rsp->pdus_setup_succ_count++; 97 | } 98 | // If all pdus_reqs failed 99 | 100 | if (rsp->pdus_setup_succ_count == 0) 101 | { 102 | pfm_log_msg(PFM_LOG_ERR,"all pdus requests failed ue_id %d", 103 | ue_id); 104 | ue_ctx_remove(ue_id); 105 | ue_ctx_commit(ue_ctx); 106 | e1ap_bearer_setup_fail(req->cucp_ue_id,ue_ctx->cucp_ue_id,FAIL_CAUSE_RNL_UNSPECIFIED,rsp); 107 | return PFM_FAILED; 108 | } 109 | ret = ue_ctx_commit(ue_ctx); 110 | if (ret == PFM_FAILED) 111 | { 112 | pfm_log_msg(PFM_LOG_ERR,"Error committing ue_ctx ue_id %d", 113 | ue_id); 114 | ue_ctx_rollback(ue_ctx); 115 | ue_ctx_commit(ue_ctx); 116 | e1ap_bearer_setup_fail(req->cucp_ue_id,ue_id,FAIL_CAUSE_RNL_UNSPECIFIED,rsp); 117 | } 118 | return ret; 119 | } 120 | -------------------------------------------------------------------------------- /e1ap_bearer_setup.h: -------------------------------------------------------------------------------- 1 | #ifndef __E1AP_BEARER_SETUP_H__ 2 | #define __E1AP_BEARER_SETUP_H__ 1 3 | 4 | #include "cuup.h" 5 | #include "e1ap_comm.h" 6 | 7 | // BEARER CONTEXT SETUP REQUEST Sec 9.2.2.1 of 3GPP TS 38.463 8 | typedef struct 9 | { 10 | uint32_t cucp_ue_id; 11 | 12 | // PDU Session Resource To Setup List 9.3.3.2 13 | uint8_t pdus_count; 14 | pdus_setup_req_info_t pdus_list[MAX_PDUS_PER_UE]; 15 | } e1ap_bearer_ctx_setup_req_t; 16 | 17 | // BEARER CONTEXT SETUP RESPONSE. sec 9.2.2.2 of 3GPP TS 38.463 18 | typedef struct 19 | { 20 | uint32_t cucp_ue_id; 21 | uint32_t cuup_ue_id; 22 | e1ap_fail_cause_t cause; // set to 0 is sucess 23 | uint8_t pdus_setup_succ_count; 24 | uint8_t pdus_setup_fail_count; 25 | pdus_setup_succ_rsp_info_t pdus_succ_list[MAX_PDUS_PER_UE]; 26 | pdus_setup_fail_rsp_info_t pdus_fail_list[MAX_PDUS_PER_UE]; 27 | } e1ap_bearer_ctx_setup_rsp_t; 28 | 29 | 30 | pfm_retval_t 31 | e1ap_bearer_ctx_setup(e1ap_bearer_ctx_setup_req_t *req,e1ap_bearer_ctx_setup_rsp_t *rsp); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /e1ap_error_indication.c: -------------------------------------------------------------------------------- 1 | #include "pfm.h" 2 | #include "cuup.h" 3 | #include "e1ap_error_indication.h" 4 | 5 | pfm_retval_t e1ap_error_indication( 6 | uint32_t cucp_ue_id, // set to zero if not included 7 | uint32_t cuup_ue_id, // set to zero if not included 8 | uint32_t cause) 9 | { 10 | // just print the argument. Implementaion can be done later 11 | printf("e1ap_error_indication(cucpUeId=%d, cuupUeId=%d,cause=%d\n", 12 | cucp_ue_id,cuup_ue_id,cause); 13 | return PFM_SUCCESS; 14 | } 15 | 16 | -------------------------------------------------------------------------------- /e1ap_error_indication.h: -------------------------------------------------------------------------------- 1 | #ifndef _E1AP_ERROR_INDICATION_H_ 2 | #define _E1AP_ERROR_INDICATION_H_ 1 3 | 4 | #include "cuup.h" 5 | #include "e1ap_comm.h" 6 | 7 | pfm_retval_t e1ap_error_indication( 8 | uint32_t cucp_ue_id, // set to zero if not included 9 | uint32_t cuup_ue_id, // set to zero if not included 10 | uint32_t cause); 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /gtp.h: -------------------------------------------------------------------------------- 1 | #ifndef __GTP_H__ 2 | #define __GTP_H__ 1 3 | 4 | #include "pfm.h" 5 | #include 6 | 7 | #define GTP_HDR_SIZE 8 8 | 9 | pfm_retval_t gtp_path_add(pfm_ip_addr_t local_ip,int local_port_no,pfm_ip_addr_t remote_ip,int remote_port_no); 10 | void gtp_data_req(const tunnel_t *t,uint32_t flow_id,struct rte_mbuf *mbuf); 11 | pfm_retval_t gtp_path_del(pfm_ip_addr_t remote_ip); 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /gtp.md: -------------------------------------------------------------------------------- 1 | # GTPv1-U GPRS Tunneling protocol Userplane 2 | 3 | GTP is a group of IP based protocols that are used within the core network since GSM, UMTS and now 5G-NR. 4 | In 5G-NR core network it is used for tunneling between the CUUP and DU (F1-U interface) and the CUUP - UPF 5 | interface (N3 interface). Our implementation uses 3GPP TS 29.281 V15.7.0 specification as reference. 6 | 7 | ## Definitions 8 | 9 | ### Common tunnel endpoint identifier (C-TEID) 10 | * it unambiguously identifies a tunnel entity in the receiving side for a given UDP/IP endpoint. 11 | * Tunnels are assigned locally and are signalled to the destination via control plane signalling. 12 | * 13 | -------------------------------------------------------------------------------- /ipcmd.txt: -------------------------------------------------------------------------------- 1 | 2 | ip [ OPTIONS ] OBJECT { COMMAND | help } 3 | 4 | where 5 | 6 | OBJECT = link(l), address(a), route(r), neigh(n), rule(ru) 7 | 8 | 9 | use 'ip OBJECT help' the get options 10 | 11 | 1. Show IP address of eth0 12 | 13 | ip addr show dev eth0 14 | 15 | 2. Assigne IP address to eth0 16 | 17 | ip addr add 192.168.121.45/24 dev eth0 18 | 19 | 3. Remove IP Address from eth0 20 | 21 | ip addr add 192.168.121.45/24 dev eth0 22 | 23 | 4. Bring eth0 interface up 24 | 25 | ip link set eth0 up 26 | 27 | 5. Dispay route 28 | 29 | ip route list 30 | 31 | 6. Dispaly route of a specific network 32 | 33 | ip r list 172.17.0.0/16 34 | 35 | 7. Add new route 36 | 37 | ip r add 172.17.0.0/16 dev eth0 38 | 39 | 8. Add default route 40 | 41 | ip r add default via 192.168.121.1 dev eth0 42 | 43 | 9. Delete route 44 | 45 | ip route del default 46 | -------------------------------------------------------------------------------- /pdcp.c: -------------------------------------------------------------------------------- 1 | #ifndef __GTP_H__ 2 | #define __GTP_H__ 1 3 | 4 | #include "pfm.h" 5 | #include "tunnel.h" 6 | #include "gtp.h" 7 | #include "pdcp.h" 8 | 9 | void pdcp_data_req(const tunnel_t *t, uint32_t flow_id, struct rte_mbuf *mbuf) 10 | { 11 | /* 12 | gtp_data_req(t, mbuf); 13 | */ 14 | } 15 | 16 | void gtp_pdcp_data_ind(const tunnel_t *t, uint32_t flow_id, struct rte_mbuf *mbuf) 17 | { 18 | /* 19 | pdcp_data_ind(t, mbuf); 20 | */ 21 | } 22 | #endif 23 | -------------------------------------------------------------------------------- /pdcp.h: -------------------------------------------------------------------------------- 1 | #ifndef __PDCP_H__ 2 | #define __PDCP_H__ 1 3 | 4 | #include "pfm.h" 5 | #include "gtp.h" 6 | #include "pdcp.h" 7 | 8 | void pdcp_data_req(const tunnel_t *t, uint32_t flow_id, struct rte_mbuf *mbuf); 9 | 10 | void gtp_pdcp_data_ind(const tunnel_t *t, uint32_t flow_id, struct rte_mbuf *mbuf); 11 | #endif 12 | -------------------------------------------------------------------------------- /pfm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_H__ 2 | #define __PFM_H__ 1 3 | 4 | #include 5 | #include "pfm_log.h" 6 | 7 | typedef enum 8 | { 9 | PROTOCOL_UDP = 17 10 | } pfm_protocol_t; 11 | 12 | typedef uint32_t pfm_ip_addr_t; 13 | 14 | typedef enum 15 | { 16 | PFM_SUCCESS, 17 | PFM_FAILED, 18 | PFM_NOT_FOUND 19 | } pfm_retval_t; 20 | 21 | typedef enum 22 | { 23 | PFM_FALSE = 0, 24 | PFM_TRUE = 1 25 | } pfm_bool_t; 26 | 27 | pfm_retval_t pfm_init(int argc, char *argv[]); 28 | 29 | pfm_retval_t pfm_start_pkt_processing(void); 30 | 31 | void pfm_data_ind( const pfm_ip_addr_t remote_ip_addr, 32 | const pfm_ip_addr_t local_ip_addr, 33 | pfm_protocol_t protocol, 34 | const int remote_port_no, 35 | const int local_port_no, 36 | struct rte_mbuf *mbuf); 37 | 38 | void pfm_data_req( const pfm_ip_addr_t local_ip_addr, 39 | const pfm_ip_addr_t remote_ip_addr, 40 | pfm_protocol_t protocol, 41 | const int local_port_no, 42 | const int remote_port_no, 43 | struct rte_mbuf *mbuf); 44 | void pfm_terminate(void); 45 | int pfm_link_open(const char *link_name); 46 | void pfm_link_close(const char *link_name); 47 | pfm_retval_t pfm_ingress_classifier_add(const int link_id, 48 | const char *kni_name, 49 | pfm_ip_addr_t local_ip_addr, 50 | const int subnet_mask_len, 51 | const int port_no); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /pfm_arp.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_ARP_H__ 2 | #define __PFM_ARP_H__ 1 3 | 4 | #include 5 | #include "pfm_comm.h" 6 | #include 7 | #include 8 | 9 | 10 | typedef struct arp_table_entry { 11 | 12 | pfm_ip_addr_t dst_ip_addr; 13 | pfm_ip_addr_t src_ip_addr; 14 | struct rte_ether_addr mac_addr; 15 | uint16_t link_id; 16 | struct rte_timer refresh_timer; 17 | uint8_t try_count; 18 | 19 | } pfm_arp_entry_t; 20 | 21 | 22 | 23 | 24 | /************************ 25 | 26 | pfm_arp_process_reply 27 | 28 | process an arp reply packet received 29 | - add new entry to arp table 30 | - update existing entries 31 | - entries are cleared after timer associated with each expires 32 | 33 | @params 34 | pkt - the rte_mbuf containing the arp reply packet 35 | link_id - the link id from which the packet was received 36 | @return 37 | 0 - normal error free operation 38 | -1 - errors like ENOSPC while making entry 39 | 40 | 41 | *************************/ 42 | 43 | 44 | int pfm_arp_process_reply(struct rte_mbuf *pkt,uint16_t link_id); 45 | 46 | /************************* 47 | pfm_arp_query 48 | 49 | checks and returns whether arp entry for specified target address exists 50 | 51 | @params 52 | ip_addr - target ip address for arp entry query 53 | @return 54 | pfm_arp_entry_t* - NULL if entry doesn't exist, else pointer to arp_entry 55 | 56 | **************************/ 57 | 58 | pfm_arp_entry_t* pfm_arp_query(pfm_ip_addr_t ip_addr); 59 | 60 | 61 | /************************* 62 | 63 | pfm_arp_print 64 | 65 | print the arp table into the specified file stream 66 | 67 | @params 68 | fp - filestream pointer to the output file 69 | @return 70 | void 71 | void pfm_arp_print(FILE *fp); 72 | *************************/ 73 | 74 | void pfm_arp_print(FILE *fp); 75 | 76 | #endif 77 | -------------------------------------------------------------------------------- /pfm_classifier.h: -------------------------------------------------------------------------------- 1 | #ifndef __CLASSIFIER_H__ 2 | #define __CLASSIFIER_H__ 1 3 | #include "pfm.h" 4 | #include "pfm_comm.h" 5 | 6 | void ingress_classify( const int link_id, 7 | struct rte_mbuf *pkts[], 8 | const int num_pkts); 9 | #endif 10 | -------------------------------------------------------------------------------- /pfm_cli.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_CLI_H__ 2 | #define __PFM_CLI_H__ 1 3 | 4 | #define CLI_MAX_ACT_COUNT 10 5 | typedef enum 6 | { 7 | PFM_CLI_CONTINUE, 8 | PFM_CLI_ERROR, 9 | PFM_CLI_EXIT, 10 | PFM_CLI_SHUTDOWN 11 | } pfm_cli_retval_t; 12 | 13 | typedef struct 14 | { 15 | const char *action_name; 16 | const char *action_desc; 17 | const char *action_syntax; 18 | pfm_cli_retval_t (*action_callback ) (FILE* fpout, char *args); 19 | } pfm_cli_action_t; 20 | 21 | typedef struct 22 | { 23 | const char *object_name; 24 | const char *object_desc; 25 | const char *object_syntax; 26 | pfm_cli_retval_t (*object_callback) 27 | (FILE* fpout, char *action, char *args); 28 | int action_count; 29 | pfm_cli_action_t *action_list[CLI_MAX_ACT_COUNT]; 30 | } pfm_cli_object_t; 31 | 32 | void pfm_cli_init(void); 33 | void pfm_cli_object_add( pfm_cli_object_t *object); 34 | void pfm_cli_action_add( pfm_cli_object_t *object, 35 | pfm_cli_action_t *action); 36 | 37 | pfm_cli_retval_t pfm_cli_exec(FILE *fpin, FILE *fpout ); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /pfm_comm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_COMM_H__ 2 | #define __PFM_COMM_H__ 1 3 | #include 4 | #include "pfm.h" 5 | #define MAX_LCORES 32 6 | #define MAX_LINK_COUNT 5 7 | #define LAST_LINK_ID MAX_LINK_COUNT 8 | #define MAX_KNI_PORTS 5 9 | #define MAX_LOCAL_IP_COUNT (MAX_KNI_PORTS*2) 10 | 11 | #define MBUF_COUNT 4096 12 | #define MBUF_CASHE_SIZE 128 13 | #define MBUF_PRIV_SIZE 0 14 | 15 | /* DPDK object names */ 16 | #define MBUF_NAME "MBUF" 17 | #define TX_RING_NAME "TXRING" 18 | #define RX_RING_NAME "RXRING" 19 | #define DIST_NAME "DISTNAME" 20 | 21 | #define TX_RING_SIZE 64 22 | #define RX_RING_SIZE TX_RING_SIZE 23 | #define TX_BURST_SIZE 32 24 | #define RX_BURST_SIZE TX_BURST_SIZE 25 | 26 | #define MAC_ADDR_SIZE RTE_ETHER_ADDR_LEN 27 | #define IP_ADDR_SIZE 4 28 | #define STR_IP_ADDR_SIZE 20 29 | #define DEFAULT_MTU_SIZE 1500 30 | #define DEFAULT_MIN_MTU_SIZE 68 31 | #define DEFAULT_MAX_MTU_SIZE 65535 32 | 33 | #define TIMER_RESOLUTION_CYCLES 20000000ULL 34 | 35 | #define ARP_TABLE_SIZE 32 36 | 37 | enum { 38 | LCORE_MAIN = 0, 39 | LCORE_RXLOOP = 1, 40 | LCORE_TXLOOP = 2, 41 | LCORE_DISTRIBUTOR = 3, 42 | LCORE_WORKER = 4, 43 | LCORE_MIN_LCORE_COUNT 44 | }; 45 | 46 | #define MAX_WORKERS (MAX_LCORES - LCORE_WORKER) 47 | typedef enum 48 | { 49 | ADMSTATE_UNLOCKED, 50 | ADMSTATE_LOCKED, 51 | } admin_state_t; 52 | 53 | typedef enum 54 | { 55 | OPSSTATE_NOTCONFIGURED, 56 | OPSSTATE_ENABLED, 57 | OPSSTATE_DISABLED, 58 | OPSSTATE_FAULTY 59 | } ops_state_t; 60 | 61 | typedef struct { 62 | int kniIdx; 63 | pfm_ip_addr_t ip_addr; 64 | pfm_ip_addr_t network_mask; 65 | pfm_ip_addr_t default_gateway_ip; 66 | } local_ip_addr_t; 67 | 68 | typedef struct { 69 | int lcore_count; 70 | int kni_count; 71 | int local_ip_count; 72 | local_ip_addr_t local_ip_addr_list[MAX_LOCAL_IP_COUNT]; 73 | struct rte_mempool *mbuf_pool; 74 | struct rte_ring *rx_ring_ptr ; 75 | struct rte_ring *tx_ring_ptr ; 76 | struct rte_kni *kni_ptr; 77 | struct rte_distributor *dist_ptr; 78 | } sys_info_t; 79 | 80 | 81 | extern volatile pfm_bool_t force_quit_g; /* all loops will use this 82 | varable to determin the looping need to continue 83 | or not. By setting this varlbale to TRUE, all loops 84 | can be terminated */ 85 | extern sys_info_t sys_info_g; 86 | 87 | 88 | #endif 89 | -------------------------------------------------------------------------------- /pfm_dist_loop.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "pfm.h" 8 | #include "pfm_comm.h" 9 | #include "pfm_link.h" 10 | #include "pfm_ring.h" 11 | #include "pfm_dist_loop.h" 12 | 13 | 14 | int dist_loop(__attribute__((unused)) void * args) { 15 | 16 | struct rte_ring *rx_dist_ring = sys_info_g.rx_ring_ptr; 17 | struct rte_ring *dist_tx_ring = sys_info_g.tx_ring_ptr; 18 | 19 | struct rte_distributor *dist = sys_info_g.dist_ptr; 20 | 21 | struct rte_mbuf *pkt_burst[RX_BURST_SIZE],*ret_pkts[TX_BURST_SIZE]; 22 | 23 | int tx_sz = 0,rx_sz = 0,ret_rx = 0,ret_tx = 0; 24 | 25 | pfm_log_msg(PFM_LOG_DEBUG, 26 | "Started distributor on lcore [%d]", 27 | rte_lcore_id()); 28 | 29 | while (force_quit_g != PFM_TRUE) { 30 | // Get packets from the ring 31 | 32 | rx_sz = rte_ring_dequeue_burst(rx_dist_ring, 33 | (void *)pkt_burst, 34 | RX_BURST_SIZE, 35 | NULL); 36 | if (rx_sz > 0) { 37 | pfm_trace_msg("Received %d packets from rx_loop on distLoop", 38 | rx_sz); 39 | } 40 | // Process these packets using distributor api 41 | 42 | tx_sz = rte_distributor_process(dist, 43 | pkt_burst, 44 | rx_sz); 45 | if (tx_sz > 0) { 46 | pfm_trace_msg("Transmitted %d packets from distLoop to various workerLoops", 47 | tx_sz); 48 | } 49 | 50 | // Get the processed packets from workers 51 | 52 | ret_rx = rte_distributor_returned_pkts(dist, 53 | ret_pkts, 54 | TX_BURST_SIZE); 55 | if (ret_rx > 0) { 56 | pfm_trace_msg("Received %d packets from workers on distLoop", 57 | ret_rx); 58 | } 59 | // Send the received packets to the txLoop 60 | 61 | ret_tx = rte_ring_enqueue_burst(dist_tx_ring, 62 | (void *)ret_pkts, 63 | ret_rx, 64 | NULL); 65 | if (ret_tx > 0) { 66 | pfm_trace_msg("Enqueued %d packets from distLoop to txLoop", 67 | ret_tx); 68 | } 69 | } 70 | 71 | pfm_log_msg(PFM_LOG_ALERT,"Forced exit from distributor"); 72 | return 1; 73 | } 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /pfm_dist_loop.h: -------------------------------------------------------------------------------- 1 | #ifndef __DISTLOOP_H__ 2 | #define __DISTLOOP_H__ 1 3 | 4 | int dist_loop(void *args); 5 | 6 | #endif 7 | -------------------------------------------------------------------------------- /pfm_kni.h: -------------------------------------------------------------------------------- 1 | #ifndef __KNI_H__ 2 | #define __KNI_H__ 1 3 | 4 | #include "pfm_comm.h" 5 | 6 | struct rte_kni *kni_open(const int link_id, 7 | const char *kni_name, 8 | const pfm_ip_addr_t ip_addr, 9 | const int subnet_mask_len); 10 | void kni_close(struct rte_kni *kni); 11 | void kni_write(struct rte_kni *kni, 12 | struct rte_mbuf *pkt_burst[], 13 | const unsigned int num_pkts); 14 | 15 | int kni_read( struct rte_mbuf *pkt_burst[], 16 | uint16_t burst_size, 17 | int *link_id); 18 | const unsigned char *kni_ipv4_mac_addr_get(pfm_ip_addr_t ip); 19 | 20 | void kni_state_change(const int link_id,const ops_state_t desired_state); 21 | void kni_ipv4_list_print(FILE *fp); 22 | void kni_ipv4_show_print(FILE *fp, char *kni_name); 23 | void pfm_kni_tx_arp( const int link_id, 24 | const pfm_ip_addr_t sender_ip_addr, 25 | const pfm_ip_addr_t target_ip_addr, 26 | const unsigned char *target_mac_addr); 27 | void pfm_kni_broadcast_arp( const pfm_ip_addr_t target_ip_addr, 28 | const unsigned char *target_mac_addr); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /pfm_link.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINK_H__ 2 | #define __LINK_H__ 1 3 | #include "pfm.h" 4 | #include "pfm_comm.h" 5 | 6 | int link_read(struct rte_mbuf *rx_pkts[],uint16_t burst_size,uint16_t *link_id); 7 | 8 | /* Application needs to implement the following callback functions */ 9 | void link_state_change_callback(int link_id, ops_state_t ops_state); 10 | void link_state_change(const int link_id,const ops_state_t desired_state); 11 | void pfm_link_list_print(FILE *fp); 12 | void pfm_link_show_print(FILE *fp, int link_id); 13 | #endif 14 | -------------------------------------------------------------------------------- /pfm_ring.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "pfm.h" 6 | #include "pfm_ring.h" 7 | 8 | void ring_write( struct rte_ring *ring_ptr, 9 | struct rte_mbuf *pkt_burst[], 10 | const int num_pkts) 11 | { 12 | int pkts_send; 13 | 14 | pkts_send = rte_ring_enqueue_burst(ring_ptr, 15 | (void **)pkt_burst,num_pkts,NULL); 16 | if (pkts_send < num_pkts) 17 | { 18 | /* some packets are not send. 19 | Drop them by releasing the buffers */ 20 | pfm_log_rte_err(PFM_LOG_WARNING, 21 | "Dropped %d slow path packets rte_kni_tx_burst()", 22 | (num_pkts-pkts_send)); 23 | 24 | for( ; pkts_send < num_pkts; pkts_send++) 25 | { 26 | rte_pktmbuf_free(pkt_burst[pkts_send]); 27 | } 28 | } 29 | return; 30 | } 31 | 32 | -------------------------------------------------------------------------------- /pfm_ring.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_RING_H__ 2 | #define __PFM_RING_H__ 1 3 | 4 | void ring_write( struct rte_ring *rx_ring_ptr, 5 | struct rte_mbuf *pkt_burst[], 6 | const int num_pkts); 7 | 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /pfm_route.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_ROUTE_H__ 2 | #define __PFM_ROUTE_H__ 1 3 | 4 | 5 | #include 6 | #include 7 | 8 | #define PFM_ROUTE_LPM_MAX_ENTRIES 32 9 | #define PFM_ROUTE_LPM_MAX_TBL8S 8 10 | #define PFM_ROUTE_LPM_FLAGS 0 11 | #define PFM_ROUTE_LPM_NAME "PFM_ROUTE_LPM" 12 | 13 | 14 | 15 | 16 | typedef struct route_table_entry { 17 | uint8_t link_id; 18 | pfm_ip_addr_t net_mask; 19 | uint8_t net_mask_depth; 20 | pfm_ip_addr_t gateway_addr; 21 | } route_t; 22 | 23 | typedef struct route_table { 24 | struct rte_lpm *lpm_mapper; 25 | route_t entries[PFM_ROUTE_LPM_MAX_ENTRIES]; 26 | } route_table_t; 27 | 28 | 29 | 30 | 31 | 32 | /***************** 33 | * 34 | * 35 | * 36 | * search for entry exisiting in ROUTE table, if not add a new entry and update LPM 37 | * 38 | * @params 39 | * link_id - the linkid that is to be updated (uint16_t) 40 | * net_mask - net_mask that is to be updated (pfm_ip_addr_t) 41 | * net_mask_depth - depth of the net_mask to be updated (uint16_t) 42 | * gateway_addr - address of gateway to be taken (pfm_ip_addr_t) 43 | * 44 | * @returns 45 | * 0 if success or -error number 46 | * 47 | * 48 | *****************/ 49 | 50 | 51 | int pfm_route_add(pfm_ip_addr_t net_mask,uint8_t net_mask_depth,pfm_ip_addr_t gateway_addr,uint16_t link); 52 | 53 | 54 | /******************** 55 | * 56 | * route_query 57 | * 58 | * search for entry for given ip address and return route info 59 | * 60 | * @params 61 | * ip_addr - key to query route table (pfm_ip_addr_t) 62 | * 63 | * @returns 64 | * the route table entry if found, null other wise (route_t) 65 | * 66 | *********************/ 67 | 68 | route_t *pfm_route_query(pfm_ip_addr_t ip_addr); 69 | 70 | /********************** 71 | * 72 | * route_print 73 | * 74 | * list all the current table entrie in route table, 75 | * and print to the file stram provided 76 | * 77 | * @params 78 | * fp - File stream to print the output to (FILE *) 79 | * 80 | **********************/ 81 | 82 | void pfm_route_print(FILE *fp); 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /pfm_rx_loop.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include "pfm.h" 9 | #include "pfm_comm.h" 10 | #include "pfm_rx_loop.h" 11 | #include "pfm_link.h" 12 | #include "pfm_classifier.h" 13 | 14 | int rx_loop( __attribute__((unused)) void *args) 15 | { 16 | struct rte_mbuf *rx_pkts[RX_BURST_SIZE*2]; 17 | uint16_t rx_sz; 18 | uint16_t link_id; 19 | uint64_t curr_ts,prev_ts = 0,diff; 20 | 21 | pfm_trace_msg("rxLoop launced on lcore [%d]", 22 | rte_lcore_id()); 23 | while(force_quit_g != PFM_TRUE) 24 | { 25 | if (PFM_FALSE != force_quit_g) 26 | { 27 | pfm_trace_msg("Stopping RX thread"); 28 | return 0; 29 | } 30 | curr_ts = rte_rdtsc(); 31 | diff = curr_ts - prev_ts; 32 | if (diff > TIMER_RESOLUTION_CYCLES) 33 | { 34 | rte_timer_manage(); 35 | prev_ts = curr_ts; 36 | } 37 | rx_sz = link_read(rx_pkts, RX_BURST_SIZE, &link_id); 38 | if (0 >= rx_sz) continue; 39 | 40 | ingress_classify(link_id,rx_pkts,rx_sz); 41 | } 42 | return 1; 43 | } 44 | 45 | 46 | -------------------------------------------------------------------------------- /pfm_rx_loop.h: -------------------------------------------------------------------------------- 1 | #ifndef __RXLOOP_H__ 2 | #define __RXLOOP_H__ 1 3 | 4 | int rx_loop( void *args); 5 | 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /pfm_tx_loop.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | 9 | #include "pfm.h" 10 | #include "pfm_comm.h" 11 | #include "pfm_tx_loop.h" 12 | #include "pfm_link.h" 13 | #include "pfm_kni.h" 14 | 15 | static void tx_burst( const int link_id, 16 | struct rte_mbuf **pkts, 17 | const int pkt_count) 18 | { 19 | int tx_pkts; 20 | tx_pkts = rte_eth_tx_burst(link_id,0,pkts,pkt_count); 21 | pfm_trace_msg("Send %d out of %d pkts to LinkId=%d", 22 | tx_pkts,pkt_count,link_id); 23 | if (tx_pkts < pkt_count) 24 | { 25 | /* free buffers of the droped Pkts */ 26 | pfm_trace_msg("Dropped %d pkts to LinkId=%d", 27 | (pkt_count - tx_pkts), link_id); 28 | for (; tx_pkts < pkt_count; tx_pkts++) 29 | { 30 | rte_pktmbuf_free(pkts[tx_pkts]); 31 | } 32 | } 33 | 34 | return; 35 | } 36 | 37 | int tx_loop( __attribute__((unused)) void *args) 38 | { 39 | struct rte_mbuf *tx_pkts[TX_BURST_SIZE]; 40 | struct rte_mbuf *out_pkts[TX_BURST_SIZE]; 41 | uint16_t in_count; 42 | int out_count; 43 | int next_pkt_idx; 44 | int link_id; 45 | int last_link_id = -1; 46 | pfm_trace_msg("TX thread started"); 47 | 48 | while(PFM_TRUE != force_quit_g) 49 | { 50 | in_count = kni_read(tx_pkts,TX_BURST_SIZE,&link_id); 51 | if ( 0 < in_count) 52 | { 53 | pfm_trace_msg("%d pkts recvd from KNI\n", 54 | in_count); 55 | tx_burst(link_id,tx_pkts,in_count); 56 | } 57 | 58 | in_count = rte_ring_dequeue_burst( 59 | sys_info_g.tx_ring_ptr, 60 | (void **)tx_pkts, 61 | TX_BURST_SIZE, 62 | NULL); 63 | if (0 < in_count ) 64 | { 65 | pfm_trace_msg("%d pkts recvd from distLoop\n", 66 | in_count); 67 | last_link_id = tx_pkts[0]->port; 68 | out_count = 0; 69 | for(next_pkt_idx=0; 70 | next_pkt_idx < in_count; next_pkt_idx++) 71 | { 72 | link_id = tx_pkts[next_pkt_idx]->port; 73 | if ( link_id != last_link_id) 74 | { 75 | /* send pkts for one link in a 76 | one bust */ 77 | tx_burst(last_link_id, 78 | out_pkts,out_count); 79 | out_count=0; 80 | last_link_id = link_id; 81 | } 82 | out_pkts[out_count] = tx_pkts[next_pkt_idx]; 83 | out_count++; 84 | } 85 | if (0 < out_count) 86 | { 87 | /* Send last burst */ 88 | tx_burst(last_link_id, 89 | out_pkts,out_count); 90 | } 91 | } 92 | 93 | } 94 | 95 | pfm_trace_msg("Exiting tx thread on lcore [%d]", 96 | rte_lcore_id()); 97 | return 1; 98 | } 99 | 100 | 101 | -------------------------------------------------------------------------------- /pfm_tx_loop.h: -------------------------------------------------------------------------------- 1 | #ifndef __TXLOOP_H__ 2 | #define __TXLOOP_H__ 1 3 | 4 | int tx_loop( void *args); 5 | 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /pfm_utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pfm.h" 7 | #include "pfm_comm.h" 8 | #include "pfm_log.h" 9 | #include "pfm_utils.h" 10 | 11 | pfm_ip_addr_t pfm_str2ip(const char *ip_str) 12 | { 13 | pfm_ip_addr_t ipn; // IP in network order 14 | pfm_ip_addr_t iph; // IP in host order 15 | int ret; 16 | 17 | ret = inet_pton(AF_INET,ip_str,&ipn); 18 | if (1 != ret) 19 | { 20 | pfm_log_std_err(PFM_LOG_WARNING, 21 | "Failed to convert IP=[%s] to " 22 | "pfm_ip_addr_t format", ip_str); 23 | return 0; 24 | } 25 | iph = ntohl(ipn); 26 | return iph; 27 | } 28 | 29 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_str) 30 | { 31 | pfm_ip_addr_t ipn; // IP in network order 32 | 33 | ipn = htonl(iph); 34 | const char *ret = inet_ntop(AF_INET,&ipn,ip_str,STR_IP_ADDR_SIZE); 35 | if (NULL == ret) 36 | { 37 | pfm_log_std_err(PFM_LOG_ERR, 38 | "Failed to IP=[0x%0X] to string format",iph); 39 | return NULL; 40 | } 41 | return ip_str; 42 | } 43 | 44 | 45 | -------------------------------------------------------------------------------- /pfm_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_UTILS_H__ 2 | #define __PFM_UTILS_H__ 1 3 | #include "pfm.h" 4 | 5 | pfm_ip_addr_t pfm_str2ip(const char *ip_str); 6 | const char *pfm_ip2str(pfm_ip_addr_t iph,char *ip_addr_str); 7 | 8 | #endif 9 | 10 | -------------------------------------------------------------------------------- /pfm_worker_loop.h: -------------------------------------------------------------------------------- 1 | #ifndef __WORKERLOOP_H__ 2 | #define ____WORKERLOOP_H__ 1 3 | 4 | int worker_loop( void *args); 5 | 6 | #endif 7 | 8 | -------------------------------------------------------------------------------- /pics/PFM_architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arv-sajeev/pfm/6aea0657d9a8e3ff68ca2bc1fcfec958ec6fcb69/pics/PFM_architecture.png -------------------------------------------------------------------------------- /run.sh: -------------------------------------------------------------------------------- 1 | sudo ./build/cuup.exe --lcore '0@0,1@1,2@0,3@1,4@0,5@1' --syslog local6 2 | 3 | -------------------------------------------------------------------------------- /sdap.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include "pfm.h" 3 | #include "pfm_comm.h" 4 | #include "pfm_utils.h" 5 | #include "tunnel.h" 6 | #include "gtp.h" 7 | #include "pdcp.h" 8 | #include "sdap.h" 9 | 10 | void pdcp_data_ind(const tunnel_t *drb_tunnel,struct rte_mbuf *mbuf) 11 | { 12 | const flow_info_t *flow_info; 13 | uint32_t drb_flow_idx; 14 | unsigned char *packet = rte_pktmbuf_mtod(mbuf,unsigned char*); 15 | char ip_str[STR_IP_ADDR_SIZE+1]; 16 | 17 | // Get pdus tunnel 18 | const tunnel_t *pdus_tunnel = tunnel_get_with_idx(drb_tunnel->drb_info.mapped_pdus_idx); 19 | 20 | // If pdus is invalid log error 21 | if (pdus_tunnel == NULL) 22 | { 23 | pfm_log_msg(PFM_LOG_ERR,"Invalid pdus index : %d",drb_tunnel->drb_info.mapped_pdus_idx); 24 | return; 25 | } 26 | 27 | // Decode flow id 28 | if (drb_tunnel->drb_info.is_ul_sdap_hdr_enabled) 29 | { 30 | // if sdap ul header is enabled extract flow-id from packet and unwrap 31 | drb_flow_idx = packet[0] & 0x3F; // QFI position bits 2-7 32 | rte_pktmbuf_adj(mbuf,SDAP_HDR_SIZE); // REMOVE SDAP header 33 | } 34 | 35 | else // flow id can be retrieved from the structure 36 | drb_flow_idx = drb_tunnel->drb_info.mapped_flow_idx; 37 | 38 | // Validate flow info 39 | flow_info = &(pdus_tunnel->pdus_info.flow_list[drb_flow_idx]); 40 | 41 | if (flow_info->flow_type != FLOW_TYPE_UL && flow_info->flow_type != FLOW_TYPE_UL_DL) 42 | { 43 | pfm_log_msg(PFM_LOG_ERR,"Invalid drb flow mapping :: %s %d flow :: %d", 44 | pfm_ip2str(drb_tunnel->key.ip_addr,ip_str),drb_tunnel->key.te_id,drb_flow_idx); 45 | return; 46 | } 47 | 48 | // Send packet to next layer UL 49 | gtp_data_req(pdus_tunnel,drb_flow_idx,mbuf); 50 | return; 51 | } 52 | 53 | void gtp_sdap_data_ind(const tunnel_t *pdus_tunnel, uint32_t flow_id, struct rte_mbuf *mbuf) 54 | { 55 | const flow_info_t *flow_info; 56 | char *ret; 57 | unsigned char *packet; 58 | char ip_str[STR_IP_ADDR_SIZE+1]; 59 | 60 | // Get flow info 61 | flow_info = &(pdus_tunnel->pdus_info.flow_list[flow_id]); 62 | 63 | // Validate flow details 64 | if (flow_info->flow_type != FLOW_TYPE_DL && flow_info->flow_type != FLOW_TYPE_UL_DL) 65 | { 66 | pfm_log_msg(PFM_LOG_ERR,"Invalid flow mapping :: %s %d flow :: %d", 67 | pfm_ip2str(pdus_tunnel->key.ip_addr,ip_str),pdus_tunnel->key.te_id,flow_id); 68 | return; 69 | } 70 | 71 | // Get DRB tunnel 72 | const tunnel_t *drb_tunnel = tunnel_get_with_idx(flow_info->mapped_drb_idx); 73 | 74 | if (drb_tunnel == NULL) 75 | { 76 | pfm_log_msg(PFM_LOG_ERR,"Invalid flow mapping :: %s %d flow :: %d", 77 | pfm_ip2str(pdus_tunnel->key.ip_addr,ip_str),drb_tunnel->key.te_id,flow_id); 78 | return; 79 | } 80 | 81 | // If sdap_dl_header is enabled fill up header 82 | if (drb_tunnel->drb_info.is_dl_sdap_hdr_enabled) 83 | { 84 | ret = rte_pktmbuf_prepend(mbuf,SDAP_HDR_SIZE); 85 | if (ret == NULL) 86 | { 87 | pfm_log_rte_err(PFM_LOG_ERR,"Insufficient HEADROOM"); 88 | return; 89 | } 90 | // TODO RDI RQI what are they and how to assign 91 | packet = rte_pktmbuf_mtod(mbuf,unsigned char *); 92 | packet[0] = flow_id; 93 | 94 | } 95 | 96 | pdcp_data_req(drb_tunnel,flow_id,mbuf); 97 | return; 98 | } 99 | -------------------------------------------------------------------------------- /sdap.h: -------------------------------------------------------------------------------- 1 | #ifndef __SDAP_H__ 2 | #define __SDAP_H__ 1 3 | 4 | #include "pfm.h" 5 | #include "gtp.h" 6 | #include "pdcp.h" 7 | 8 | #define SDAP_HDR_SIZE 1 9 | void pdcp_data_ind(const tunnel_t *t,struct rte_mbuf *mbuf); 10 | void gtp_sdap_data_ind(const tunnel_t *t,uint32_t flow_id,struct rte_mbuf *mbuf); 11 | 12 | #endif 13 | 14 | -------------------------------------------------------------------------------- /test/F1u.edpat: -------------------------------------------------------------------------------- 1 | #addr.edpat; 2 | 3 | !---------------------F1u Subnet 4 | $LOCALMAC = $F1u_LOCAL_MAC; 5 | $LOCALIP = $F1u_LOCAL_IP; 6 | $REMOTEMAC = $F1u_REMOTE_MAC; 7 | $REMOTEIP = $F1u_REMOTE_IP1; 8 | $ETHPORT = $F1u_ETHPORT; 9 | 10 | @ARP_F1u0; 11 | #arp.edpat; 12 | 13 | <$ETHPORT 14 | !----------------Ethernet header 15 | $LOCALMAC !00-05 Dst MAC Addr 16 | $REMOTEMAC !06-11 Src MAC Addr 17 | 08 06 !12-13 EtherType=ARP 18 | !----------------ARP Reply packet 19 | 00 01 !14-15 HW Type=Ethernet 20 | 08 00 !16-17 Protocol Type=IPV4 21 | 06 !18 HW Size 22 | 04 !19 Protocl Size 23 | 00 02 !20-21 OpCode=Request 24 | $REMOTEMAC !22-27 Sender MAC Addr 25 | $REMOTEIP !28-31 Sender IP Addr 26 | $LOCALMAC !32-37 Target MAC Addr 27 | $LOCALIP; !38-41 Target IP Addr 28 | 29 | @ARP_F1u1; 30 | $REMOTEIP = $F1u_REMOTE_IP2; 31 | #arp.edpat; 32 | 33 | <$ETHPORT 34 | !----------------Ethernet header 35 | $LOCALMAC !00-05 Dst MAC Addr 36 | $REMOTEMAC !06-11 Src MAC Addr 37 | 08 06 !12-13 EtherType=ARP 38 | !----------------ARP Reply packet 39 | 00 01 !14-15 HW Type=Ethernet 40 | 08 00 !16-17 Protocol Type=IPV4 41 | 06 !18 HW Size 42 | 04 !19 Protocl Size 43 | 00 02 !20-21 OpCode=Request 44 | $REMOTEMAC !22-27 Sender MAC Addr 45 | $REMOTEIP !28-31 Sender IP Addr 46 | $LOCALMAC !32-37 Target MAC Addr 47 | $LOCALIP; !38-41 Target IP Addr 48 | 49 | 50 | -------------------------------------------------------------------------------- /test/GTP.edpat: -------------------------------------------------------------------------------- 1 | 2 | 3 | >$ETHPORT 4 | !----------------Ethernet header 5 | $REMOTEMAC !00-05 Dst MAC Addr 6 | $LOCALMAC !06-11 Src MAC Addr 7 | 08 00 !12-13 EtherType=IPv4 8 | !IP Header 9 | 45 !14 Version and Header Length 10 | 00 !15 DSCP 11 | 00 2E !16-17 Lenght including IP Header. 0x2E = 46 12 | 7d 86 !18-19 Identifier 13 | 40 00 !20-21 Flags 14 | 40 !22 Time to Live 15 | 11 !23 Protocol = UDP 16 | &14-33 !24-25 Checksum of the complete IP header 17 | $LOCALIP !26-29 Soruce IP 18 | $REMOTEIP !30-33 Dsp IP 19 | !Below is the UDP Header 20 | 01 02 !34-35 Source Port 21 | $GTP_PORTNO !36-37 Destination Port 22 | 00 1A !38-39 Length of UDP header and Data. 26 bytes 23 | 00 00 !40-41 Checksum. set to 00 00 as checksum is not used 24 | 25 | !Below is GTP Header. Not yet complete 26 | 00 11 22 33 44 55 66 77 !42-49 27 | 00 11 22 33 44 55 66 77 88 99; !50-60 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/NGu.edpat: -------------------------------------------------------------------------------- 1 | #addr.edpat; 2 | 3 | !---------------------NGu Subnet 4 | $LOCALMAC = $NGu_LOCAL_MAC; 5 | $LOCALIP = $NGu_LOCAL_IP; 6 | $REMOTEMAC = $NGu_REMOTE_MAC; 7 | $REMOTEIP = $NGu_REMOTE_IP1; 8 | $ETHPORT = $NGu_ETHPORT; 9 | 10 | @ARP_NGu0; 11 | #arp.edpat; 12 | 13 | <$ETHPORT 14 | !----------------Ethernet header 15 | $LOCALMAC !00-05 Dst MAC Addr 16 | $REMOTEMAC !06-11 Src MAC Addr 17 | 08 06 !12-13 EtherType=ARP 18 | !----------------ARP Reply packet 19 | 00 01 !14-15 HW Type=Ethernet 20 | 08 00 !16-17 Protocol Type=IPV4 21 | 06 !18 HW Size 22 | 04 !19 Protocl Size 23 | 00 02 !20-21 OpCode=Request 24 | $REMOTEMAC !22-27 Sender MAC Addr 25 | $REMOTEIP !28-31 Sender IP Addr 26 | $LOCALMAC !32-37 Target MAC Addr 27 | $LOCALIP; !38-41 Target IP Addr 28 | 29 | @ARP_NGu1; 30 | $REMOTEIP = $NGu_REMOTE_IP2; 31 | #arp.edpat; 32 | 33 | <$ETHPORT 34 | !----------------Ethernet header 35 | $LOCALMAC !00-05 Dst MAC Addr 36 | $REMOTEMAC !06-11 Src MAC Addr 37 | 08 06 !12-13 EtherType=ARP 38 | !----------------ARP Reply packet 39 | 00 01 !14-15 HW Type=Ethernet 40 | 08 00 !16-17 Protocol Type=IPV4 41 | 06 !18 HW Size 42 | 04 !19 Protocl Size 43 | 00 02 !20-21 OpCode=Request 44 | $REMOTEMAC !22-27 Sender MAC Addr 45 | $REMOTEIP !28-31 Sender IP Addr 46 | $LOCALMAC !32-37 Target MAC Addr 47 | $LOCALIP; !38-41 Target IP Addr 48 | 49 | -------------------------------------------------------------------------------- /test/addr.edpat: -------------------------------------------------------------------------------- 1 | $NGu_LOCAL_MAC = 08 00 27 ba ce f8; 2 | $NGu_REMOTE_MAC = 08 00 27 5a 35 64; 3 | $F1u_LOCAL_MAC = 08 00 27 0D BF 9D; 4 | $F1u_REMOTE_MAC = 08 00 27 22 D0 1F; 5 | $NGu_LOCAL_IP = c0 a8 39 73; ! 192.168.57.115 6 | $NGu_REMOTE_IP1 = c0 a8 39 C8; ! 192.168.57.200 7 | $NGu_REMOTE_IP2 = c0 a8 39 C9; ! 192.168.57.201 8 | $F1u_LOCAL_IP = c0 a8 3A 73; ! 192.168.58.115 9 | $F1u_REMOTE_IP1 = c0 a8 3A CA; ! 192.168.58.202 10 | $F1u_REMOTE_IP2 = c0 a8 3A CB; ! 192.168.58.203 11 | $NGu_ETHPORT = enp0s8; 12 | $F1u_ETHPORT = eth3; 13 | $GTP_PORTNO = 08 68; Port no 2152 = 0x0868 14 | 15 | -------------------------------------------------------------------------------- /test/arp.edpat: -------------------------------------------------------------------------------- 1 | 2 | >$ETHPORT 3 | !----------------Ethernet header 4 | $REMOTEMAC !00-05 Dst MAC Addr 5 | $LOCALMAC !06-11 Src MAC Addr 6 | 08 06 !12-13 EtherType=ARP 7 | !----------------ARP Request packet 8 | 00 01 !14-15 HW Type=Ethernet 9 | 08 00 !16-17 Protocol Type=IPv4 10 | 06 !18 HW Size 11 | 04 !19 Protocl Size 12 | 00 01 !20-21 OpCode=Request 13 | $LOCALMAC !22-27 Sender MAC Addr 14 | $LOCALIP !28-31 Sender IP Addr 15 | 00 00 00 00 00 00 !32-37 Target MAC Addr 16 | $REMOTEIP !38-41 Target IP Addr 17 | !----------------Padding 18 | 00 00 00 00 00 00 19 | 00 00 00 00 00 00 00 00 00 00 00 00; 20 | 21 | <$ETHPORT 22 | !----------------Ethernet header 23 | $LOCALMAC !00-05 Dst MAC Addr 24 | $REMOTEMAC !06-11 Src MAC Addr 25 | 08 06 !12-13 EtherType=ARP 26 | !----------------ARP Reply packet 27 | 00 01 !14-15 HW Type=Ethernet 28 | 08 00 !16-17 Protocol Type=IPV4 29 | 06 !18 HW Size 30 | 04 !19 Protocl Size 31 | 00 02 !20-21 OpCode=Request 32 | $REMOTEMAC !22-27 Sender MAC Addr 33 | $REMOTEIP !28-31 Sender IP Addr 34 | $LOCALMAC !32-37 Target MAC Addr 35 | $LOCALIP; !38-41 Target IP Addr 36 | 37 | -------------------------------------------------------------------------------- /test/echo.edpat: -------------------------------------------------------------------------------- 1 | 2 | >$ETHPORT 3 | !----------------Ethernet header 4 | $REMOTEMAC !00-05 Dst MAC Addr 5 | $LOCALMAC !06-11 Src MAC Addr 6 | 08 00 !12-13 EtherType=IPv4 7 | !IP Header 8 | 45 !14 Version and Header Length 9 | 00 !15 DSCP 10 | 00 54 !16-17 Total Lenght 11 | 7d 86 !18-19 Identifier 12 | 40 00 !20-21 Flags 13 | 40 !22 Time to Live 14 | 01 !23 Protocol = ICMP 15 | &14-33 !24-25 Checksum of the complete IP header 16 | $LOCALIP !26-29 Soruce IP 17 | $REMOTEIP !30-33 Dsp IP 18 | !Below is the ICMP Payload 19 | 08 !34 ICMP Type = Echo Request 20 | 00 !35 Code 21 | &34-97 !36-37 Checksum 22 | 4c 09 !38-39 Identifier 23 | 00 04 !40-41 Sequence No 24 | !Rest is data 25 | b8 3d 7e 64 00 00 00 00 00 00 26 | 00 00 00 00 00 00 00 00 00 00 27 | 00 00 00 00 00 00 00 00 00 00 28 | 00 00 00 00 00 00 00 00 00 00 29 | 00 00 00 00 00 00 00 00 00 00 30 | 00 00 00 00 00 00; 31 | 32 | <$ETHPORT 33 | !----------------Ethernet header 34 | $LOCALMAC !00-05 Dst MAC Addr 35 | $REMOTEMAC !05-11 Src MAC Addr 36 | 08 00 !12-13 EtherType=ICMP 37 | !Below is IP Header 38 | 45 !14 IP Version & Header Len 39 | 00 !15 DSCP 40 | 00 54 !16-17 Total Length 41 | * * !18-19 Identifier 42 | 00 00 !20-21 Flags 43 | 40 !22 Time to live 44 | 01 !23 Protocol = ICMP 45 | * * !24-25 Checksum of complete IP header. 46 | $REMOTEIP !26-29 Souce IP 47 | $LOCALIP !30-33 Dest IP 48 | !Below is the ICMP Payload 49 | 00 !34 ICMP Type = Echo Reply 50 | 00 !35 Code 51 | * * !36-37 Cheksum 52 | 4c 09 !38-39 Identifier 53 | 00 04 !40-41 Sequnce No 54 | !Rest is data 55 | b8 3d 7e 64 00 00 00 00 00 00 56 | 00 00 00 00 00 00 00 00 00 00 57 | 00 00 00 00 00 00 00 00 00 00 58 | 00 00 00 00 00 00 00 00 00 00 59 | 00 00 00 00 00 00 00 00 00 00 60 | 00 00 00 00 00 00; 61 | 62 | -------------------------------------------------------------------------------- /test/gtp.edpat: -------------------------------------------------------------------------------- 1 | 2 | 3 | >$ETHPORT 4 | !----------------Ethernet header 5 | $REMOTEMAC !00-05 Dst MAC Addr 6 | $LOCALMAC !06-11 Src MAC Addr 7 | 08 00 !12-13 EtherType=IPv4 8 | !IP Header 9 | 45 !14 Version and Header Length 10 | 00 !15 DSCP 11 | 00 2E !16-17 Lenght including IP Header. 0x2E = 46 12 | 7d 86 !18-19 Identifier 13 | 40 00 !20-21 Flags 14 | 40 !22 Time to Live 15 | 11 !23 Protocol = UDP 16 | &14-33 !24-25 Checksum of the complete IP header 17 | $LOCALIP !26-29 Soruce IP 18 | $REMOTEIP !30-33 Dsp IP 19 | !Below is the UDP Header 20 | 01 02 !34-35 Source Port 21 | $GTP_PORTNO !36-37 Destination Port 22 | 00 1A !38-39 Length of UDP header and Data. 26 bytes 23 | 00 00 !40-41 Checksum. set to 00 00 as checksum is not used 24 | 25 | !Below is GTP Header. Not yet complete 26 | 00 11 22 33 44 55 66 77 !42-49 27 | 00 11 22 33 44 55 66 77 88 99; !50-60 28 | 29 | 30 | -------------------------------------------------------------------------------- /test/gtp_main.edpat: -------------------------------------------------------------------------------- 1 | 2 | >$ETHPORT 3 | !----------------Ethernet header 4 | $REMOTEMAC !00-05 Dst MAC Addr 5 | $LOCALMAC !06-11 Src MAC Addr 6 | 08 00 !12-13 EtherType=IPv4 7 | !IP Header 8 | 45 !14 Version and Header Length 9 | 00 !15 DSCP 10 | 00 2E !16-17 Lenght including IP Header. 0x2E = 46 11 | 7d 86 !18-19 Identifier 12 | 40 00 !20-21 Flags 13 | 40 !22 Time to Live 14 | 11 !23 Protocol = UDP 15 | &14-33 !24-25 Checksum of the complete IP header 16 | $LOCALIP !26-29 Soruce IP 17 | $REMOTEIP !30-33 Dsp IP 18 | !Below is the UDP Header 19 | 01 02 !34-35 Source Port 20 | $GTP_PORTNO !36-37 Destination Port 21 | 00 1A !38-39 Length of UDP header and Data. 26 bytes 22 | 00 00 !40-41 Checksum. set to 00 00 as checksum is not used 23 | 24 | !Below is GTP Header. Not yet complete 25 | 00 11 22 33 44 55 66 77 !42-49 26 | 00 11 22 33 44 55 66 77 88 99; !50-60 27 | 28 | 29 | <$ETHPORT 30 | !----------------Ethernet header 31 | $LOCALMAC !00-05 Dst MAC Addr 32 | $REMOTEMAC !06-11 Src MAC Addr 33 | 08 00 !12-13 EtherType=IPv4 34 | !IP Header 35 | 45 !14 Version and Header Length 36 | 00 !15 DSCP 37 | 00 2E !16-17 Lenght including IP Header. 0x2E = 46 38 | 7d 86 !18-19 Identifier 39 | 40 00 !20-21 Flags 40 | 40 !22 Time to Live 41 | 11 !23 Protocol = UDP 42 | * * !24-25 Checksum of the complete IP header 43 | $LOCALIP !26-29 Soruce IP 44 | $REMOTEIP !30-33 Dsp IP 45 | !Below is the UDP Header 46 | 01 02 !34-35 Source Port 47 | $GTP_PORTNO !36-37 Destination Port 48 | 00 1A !38-39 Length of UDP header and Data. 26 bytes 49 | 00 00 !40-41 Checksum. set to 00 00 as checksum is not used 50 | 51 | !Below is GTP Header. Not yet complete 52 | 00 11 22 33 44 55 66 77 !42-49 53 | 00 11 22 33 44 55 66 77 88 99; !50-60 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /test/pfm_arp_test/addr.edpat: -------------------------------------------------------------------------------- 1 | $TCLOCALMAC = 08 00 27 17 8D B4; 2 | $TCLOCALIP = c0 a8 38 6F; ! 192.168.56.111 3 | $PFMREMOTEMAC = 08 00 27 5A 31 64; 4 | $PFMREMOTEIP = c0 a8 39 c8; 5 | 6 | -------------------------------------------------------------------------------- /test/pfm_arp_test/pfm_arp_test1.edpat: -------------------------------------------------------------------------------- 1 | #addr.edpat; 2 | 3 | > eth1 4 | !------Ethernet header 5 | $PFMREMOTEMAC !00-05 ! Destination MAC 6 | $TCLOCALMAC !06-11 ! Source MAC 7 | 08 00 !12-13 ! Ether type ipv4 8 | !------IPV4 header 9 | 45 !14 ! Version and IHL 10 | 00 !15 ! DSCP 11 | 00 2E !16-17 ! Total length 12 | 7D 86 !18-19 ! fragment ID 13 | 40 00 !20-21 ! flags 14 | 40 !22 ! Time to live 15 | 11 !23 ! Protocol UDP 17 16 | &14-33 !24-25 ! Check sum of the IP header 17 | $TCLOCALIP !26-29 ! Source IP 18 | $PFMREMOTEIP !30-33 ! Destination IP 19 | !------UDP header 20 | 01 02 !34-35 ! Source port 21 | 08 68 !36-37 ! Destination port ! GTP port no 2152 0868 22 | 00 1A !38-39 ! Lenght of the UDP header 26 23 | 00 00 !40 41 ! Check sum 24 | 11 22 33 44 55 66 77 88 25 | 88 77 66 55 44 33 22 11; 26 | -------------------------------------------------------------------------------- /tunnel.h: -------------------------------------------------------------------------------- 1 | #ifndef __TUNNEL_H__ 2 | #define __TUNNEL_H__ 1 3 | #include "pfm.h" 4 | #include "cuup.h" 5 | 6 | typedef enum 7 | { 8 | TUNNEL_TYPE_PDUS, 9 | TUNNEL_TYPE_DRB, 10 | } tunnel_type_t; 11 | 12 | typedef enum 13 | { 14 | FLOW_TYPE_UNUSED, 15 | FLOW_TYPE_DL, 16 | FLOW_TYPE_UL, 17 | FLOW_TYPE_UL_DL, 18 | 19 | } flow_type_t; 20 | 21 | typedef struct 22 | { 23 | unsigned int drb_id:5; 24 | unsigned int is_default:1; 25 | unsigned int is_dl_sdap_hdr_enabled:1; 26 | unsigned int is_ul_sdap_hdr_enabled:1; 27 | uint32_t mapped_flow_idx; // valid only if is_ul_sdap_hdr_enabled is not enabled 28 | uint32_t mapped_pdus_idx; 29 | } drb_info_t; 30 | 31 | typedef struct 32 | { 33 | flow_type_t flow_type:2; 34 | unsigned int r_qos_status:2; 35 | uint32_t mapped_drb_idx; 36 | } flow_info_t; 37 | 38 | typedef struct 39 | { 40 | unsigned int pdus_id:8; 41 | unsigned int flow_count:6; 42 | uint64_t ul_new_flow_detected_bit_map; 43 | flow_info_t flow_list[MAX_FLOWS_PER_PDUS]; 44 | } pdus_info_t; 45 | 46 | typedef struct 47 | { 48 | uint32_t ip_addr; 49 | uint32_t te_id; 50 | } tunnel_key_t; 51 | 52 | typedef struct 53 | { 54 | tunnel_key_t key; 55 | pfm_ip_addr_t remote_ip; 56 | uint32_t remote_te_id; 57 | tunnel_type_t tunnel_type:2; 58 | pfm_bool_t is_row_used:1; 59 | union 60 | { 61 | pdus_info_t pdus_info; 62 | drb_info_t drb_info; 63 | }; 64 | } tunnel_t; 65 | 66 | 67 | const tunnel_t* tunnel_get(tunnel_key_t *key); 68 | const tunnel_t* tunnel_get_with_idx(uint32_t tunnel_idx); 69 | tunnel_t * tunnel_add(tunnel_key_t *key); 70 | pfm_retval_t tunnel_remove(tunnel_key_t *key); 71 | tunnel_t * tunnel_modify(tunnel_key_t *key); 72 | pfm_retval_t tunnel_commit(tunnel_t* nt); 73 | void tunnel_print_show(FILE *fp, tunnel_key_t *key); 74 | void tunnel_print_list(FILE *fp, tunnel_type_t ttype); 75 | pfm_retval_t tunnel_key_alloc(pfm_ip_addr_t ip,tunnel_type_t ttype,tunnel_key_t *key); 76 | pfm_retval_t tunnel_remove(tunnel_key_t *key); 77 | pfm_retval_t tunnel_rollback(tunnel_t *nt); 78 | #endif 79 | -------------------------------------------------------------------------------- /ue_ctx.h: -------------------------------------------------------------------------------- 1 | #ifndef __UE_CTX_H__ 2 | #define __UE_CTX_H__ 1 3 | 4 | #include "tunnel.h" 5 | 6 | 7 | typedef struct 8 | { 9 | uint32_t cuup_ue_id; // 32 bit gNB-CU-UP UE E1AP ID 10 | uint32_t cucp_ue_id; // 32 bit gNB-CU-CP UE E1AP ID 11 | uint8_t pdus_count:8; // PDU Session count 12 | uint8_t drb_count:5; 13 | uint8_t new_ul_flow_detected_count:5; 14 | pfm_bool_t is_row_used:1; 15 | tunnel_t * pdus_tunnel_list[MAX_PDUS_PER_UE]; 16 | tunnel_t * drb_tunnel_list[MAX_DRB_PER_UE]; 17 | } ue_ctx_t; 18 | 19 | ue_ctx_t * ue_ctx_add(uint32_t ue_id); 20 | pfm_retval_t ue_ctx_remove(uint32_t ue_id); 21 | ue_ctx_t * ue_ctx_modify(uint32_t ue_id); 22 | pfm_retval_t ue_ctx_commit(ue_ctx_t *new_ctx); 23 | const ue_ctx_t * ue_ctx_get(uint32_t ue_id); 24 | void ue_ctx_print_list(FILE *fp); 25 | void ue_ctx_print_show(FILE *fp, uint32_t ue_id); 26 | pfm_retval_t ue_ctx_id_alloc(uint32_t *ue_id); 27 | pfm_retval_t ue_ctx_rollback(ue_ctx_t *ue_ctx); 28 | #endif 29 | 30 | -------------------------------------------------------------------------------- /unittests/arp/.main.c.swp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/arv-sajeev/pfm/6aea0657d9a8e3ff68ca2bc1fcfec958ec6fcb69/unittests/arp/.main.c.swp -------------------------------------------------------------------------------- /unittests/arp/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2010-2014 Intel Corporation 3 | 4 | # binary name 5 | APP = cuup.exe 6 | 7 | # all source are stored in SRCS-y 8 | SRCS-y := cuup.c \ 9 | pfm.c \ 10 | pfm_log.c \ 11 | pfm_worker_loop.c \ 12 | pfm_link.c \ 13 | pfm_rx_loop.c \ 14 | pfm_tx_loop.c \ 15 | pfm_kni.c \ 16 | pfm_ring.c \ 17 | pfm_classifier.c \ 18 | pfm_dist_loop.c \ 19 | pfm_cli.c \ 20 | pfm_route.c \ 21 | pfm_arp.c \ 22 | pfm_utils.c 23 | 24 | # Build using pkg-config variables if possible 25 | ifeq ($(shell pkg-config --exists libdpdk && echo 0),0) 26 | 27 | all: shared 28 | .PHONY: shared static 29 | shared: build/$(APP)-shared 30 | ln -sf $(APP)-shared build/$(APP) 31 | static: build/$(APP)-static 32 | ln -sf $(APP)-static build/$(APP) 33 | 34 | PKGCONF ?= pkg-config 35 | 36 | PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) 37 | CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) 38 | CFLAGS += -DALLOW_EXPERIMENTAL_API 39 | LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) 40 | LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) 41 | 42 | build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build 43 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 44 | 45 | build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build 46 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) 47 | 48 | build: 49 | @mkdir -p $@ 50 | 51 | .PHONY: clean 52 | clean: 53 | rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared 54 | test -d build && rmdir -p build || true 55 | 56 | else # Build using legacy build system 57 | 58 | ifeq ($(RTE_SDK),) 59 | $(error "Please define RTE_SDK environment variable") 60 | endif 61 | 62 | # Default target, detect a build directory, by looking for a path with a .config 63 | RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) 64 | 65 | include $(RTE_SDK)/mk/rte.vars.mk 66 | 67 | ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),y) 68 | $(error This application can only operate in a linux environment, \ 69 | please change the definition of the RTE_TARGET environment variable) 70 | endif 71 | 72 | #CFLAGS += -O3 -g -DTRACE -DCONSLOG 73 | CFLAGS += -O3 -g -DTRACE 74 | CFLAGS += -DALLOW_EXPERIMENTAL_API 75 | CFLAGS += $(WERROR_FLAGS) 76 | 77 | include $(RTE_SDK)/mk/rte.extapp.mk 78 | endif 79 | -------------------------------------------------------------------------------- /unittests/arp/cuup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pfm.h" 7 | #include "pfm_comm.h" 8 | #include "pfm_utils.h" 9 | #include "pfm_cli.h" 10 | 11 | #define GTP_PORTNO 2152 12 | 13 | static void terminate_program(void) 14 | { 15 | pfm_terminate(); 16 | pfm_log_close(); 17 | return; 18 | } 19 | 20 | static void signal_handler(int sig_num) 21 | { 22 | if ( ( SIGINT == sig_num ) || 23 | ( SIGTERM == sig_num )) 24 | { 25 | pfm_trace_msg("Signal %d received, preparing to exit..", 26 | sig_num); 27 | terminate_program(); 28 | } 29 | return; 30 | } 31 | 32 | 33 | int main(int argc, char *argv[]) 34 | { 35 | pfm_retval_t ret_val; 36 | pfm_cli_retval_t cli_ret_val; 37 | int ret; 38 | int lcore_id; 39 | 40 | /* initialize logging and tracing libs*/ 41 | pfm_log_open("CUUP",PFM_LOG_DEBUG); 42 | 43 | /* install signal handlers */ 44 | signal(SIGINT, signal_handler); 45 | signal(SIGTERM, signal_handler); 46 | 47 | ret_val = pfm_init(argc, argv); 48 | if (PFM_SUCCESS != ret_val) 49 | { 50 | terminate_program(); 51 | exit(1); 52 | } 53 | 54 | pfm_link_open("0000:00:09.0"); 55 | pfm_link_open("0000:00:0a.0"); 56 | 57 | pfm_ip_addr_t ip; 58 | 59 | ip = pfm_str2ip("192.168.57.200"); 60 | ret_val = pfm_ingress_classifier_add(0,"NGu0",ip,24,GTP_PORTNO); 61 | 62 | ip = pfm_str2ip("192.168.57.201"); 63 | ret_val = pfm_ingress_classifier_add(0,"NGu1",ip,24,GTP_PORTNO); 64 | 65 | 66 | ip = pfm_str2ip("192.168.58.202"); 67 | ret_val = pfm_ingress_classifier_add(1,"F1u0",ip,24,GTP_PORTNO); 68 | 69 | ip = pfm_str2ip("192.168.58.203"); 70 | ret_val = pfm_ingress_classifier_add(1,"F1u1",ip,24,GTP_PORTNO); 71 | 72 | if (PFM_SUCCESS != ret_val) 73 | { 74 | pfm_log_msg(PFM_LOG_WARNING, 75 | "KNI Port creation failed"); 76 | exit(3); 77 | } 78 | 79 | ret_val = pfm_start_pkt_processing(); 80 | if (PFM_SUCCESS != ret_val) 81 | { 82 | pfm_log_msg(PFM_LOG_WARNING, 83 | "DPPF_StartPktProcessing() failed"); 84 | terminate_program(); 85 | exit(2); 86 | } 87 | 88 | pfm_cli_init(); 89 | 90 | cli_ret_val = PFM_CLI_CONTINUE; 91 | while((PFM_CLI_EXIT != cli_ret_val) && 92 | (PFM_CLI_SHUTDOWN != cli_ret_val)) 93 | { 94 | cli_ret_val = pfm_cli_exec(stdin,stdout); 95 | }; 96 | 97 | 98 | RTE_LCORE_FOREACH_SLAVE(lcore_id) 99 | { 100 | ret = rte_eal_wait_lcore(lcore_id); 101 | if (0 != ret) 102 | { 103 | pfm_log_rte_err(PFM_LOG_WARNING, 104 | "rte_eal_wait_lcore(lcore=%d) failed", 105 | lcore_id); 106 | exit(3); 107 | } 108 | else 109 | { 110 | pfm_trace_msg("lcore %d stopped", lcore_id); 111 | } 112 | } 113 | pfm_trace_msg("All slave threads stopped"); 114 | 115 | terminate_program(); 116 | exit(0); 117 | } 118 | 119 | /************* 120 | * pfm_data_ind() 121 | * 122 | * When DPPF wants to pass a packet to applicaion, it invokes this function. 123 | * This is a dummy function which need to be implemented by application 124 | * It needs to be replaced when applicaiton is implemented. 125 | * 126 | ****************/ 127 | void pfm_data_ind( const pfm_ip_addr_t remote_ip_addr, 128 | const pfm_ip_addr_t local_ip_addr, 129 | pfm_protocol_t protocol, 130 | const int remote_port_no, 131 | const int local_port_no, 132 | struct rte_mbuf *mbuf) 133 | { 134 | unsigned char *pkt; 135 | int pkt_len; 136 | 137 | char local_ip_addr_str[STR_IP_ADDR_SIZE]; 138 | char remote_ip_addr_str[STR_IP_ADDR_SIZE]; 139 | 140 | printf("Invoked pfm_data_ind(remote_ip=%s,local_ip=%s," 141 | "protocol=%d," 142 | "remote_port=%d,local_port=%d,bufPtr=%p\n", 143 | pfm_ip2str(remote_ip_addr,remote_ip_addr_str), 144 | pfm_ip2str(local_ip_addr,local_ip_addr_str), 145 | protocol, 146 | remote_port_no, 147 | local_port_no, 148 | mbuf); 149 | 150 | pkt = rte_pktmbuf_mtod(mbuf,unsigned char*); 151 | pkt_len = mbuf->pkt_len; 152 | pfm_trace_pkt_hdr(pkt,pkt_len,"Rx on worker [%d]",rte_lcore_id()); 153 | pfm_trace_pkt(pkt,pkt_len,"Rx on worker [%d]",rte_lcore_id()); 154 | 155 | pfm_data_req( local_ip_addr, remote_ip_addr, 156 | protocol, 157 | local_port_no,remote_port_no, 158 | mbuf); 159 | 160 | return; 161 | } 162 | 163 | 164 | -------------------------------------------------------------------------------- /unittests/arp/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include "pfm.h" 6 | #include "pfm_comm.h" 7 | #include "pfm_log.h" 8 | #include "pfm_link.h" 9 | #inlcude "pfm_arp.h" 10 | 11 | static void terminate_program(void) { 12 | pfm_terminate(); 13 | pfm_log_close(); 14 | } 15 | 16 | static void signal_handler(int sig_num) { 17 | if ((SIGINT == sig_num) || (SIGTERM == sig_num)) { 18 | pfm_trace_msg("Signal %d received, preparing to exit..", 19 | sig_num); 20 | terminate_program(); 21 | } 22 | return; 23 | } 24 | 25 | 26 | int main(int argc,char* argv[]) { 27 | pfm_retval_t ret_val; 28 | int ret; 29 | int lcore_id; 30 | 31 | pfm_log_open("ARP-UNIT-TEST",PFM_LOG_DEBUG); 32 | signal(SIGINT,signal_handler); 33 | signal(SIGTERM,signal_handler); 34 | 35 | ret_val = pfm_init(argc,argv); 36 | if (PFM_SUCCESS != ret_val) { 37 | terminate_program(); 38 | exit(1); 39 | } 40 | 41 | pfm_link_open("0000:00;09.0"); 42 | pfm_trace_msg("Init all done"); 43 | 44 | while (1) { 45 | ret = link_read( 46 | 47 | } 48 | 49 | 50 | 51 | 52 | } 53 | 54 | 55 | 56 | -------------------------------------------------------------------------------- /unittests/arp/pfm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_H__ 2 | #define __PFM_H__ 1 3 | 4 | #include 5 | #include "pfm_log.h" 6 | 7 | typedef enum 8 | { 9 | PROTOCOL_UDP = 17 10 | } pfm_protocol_t; 11 | 12 | typedef uint32_t pfm_ip_addr_t; 13 | 14 | typedef enum 15 | { 16 | PFM_SUCCESS, 17 | PFM_FAILED, 18 | PFM_NOT_FOUND 19 | } pfm_retval_t; 20 | 21 | typedef enum 22 | { 23 | PFM_FALSE = 0, 24 | PFM_TRUE = 1 25 | } pfm_bool_t; 26 | 27 | pfm_retval_t pfm_init(int argc, char *argv[]); 28 | 29 | pfm_retval_t pfm_start_pkt_processing(void); 30 | 31 | void pfm_data_ind( const pfm_ip_addr_t remote_ip_addr, 32 | const pfm_ip_addr_t local_ip_addr, 33 | pfm_protocol_t protocol, 34 | const int remote_port_no, 35 | const int local_port_no, 36 | struct rte_mbuf *mbuf); 37 | 38 | void pfm_data_req( const pfm_ip_addr_t local_ip_addr, 39 | const pfm_ip_addr_t remote_ip_addr, 40 | pfm_protocol_t protocol, 41 | const int local_port_no, 42 | const int remote_port_no, 43 | struct rte_mbuf *mbuf); 44 | void pfm_terminate(void); 45 | int pfm_link_open(const char *link_name); 46 | void pfm_link_close(const char *link_name); 47 | pfm_retval_t pfm_ingress_classifier_add(const int link_id, 48 | const char *kni_name, 49 | pfm_ip_addr_t local_ip_addr, 50 | const int subnet_mask_len, 51 | const int port_no); 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /unittests/arp/pfm_arp.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_ROUTE_H__ 2 | #define __PFM_ROUTE_H__ 1 3 | 4 | #include 5 | #include "pfm_comm.h" 6 | #include 7 | #include 8 | 9 | 10 | typedef struct arp_table_entry { 11 | 12 | pfm_ip_addr_t dst_ip_addr; 13 | pfm_ip_addr_t src_ip_addr; 14 | struct rte_ether_addr mac_addr; 15 | uint16_t link_id; 16 | struct rte_timer* refresh_timer; 17 | uint8_t try_count; 18 | 19 | } arp_entry_t; 20 | 21 | typedef struct callback_args { 22 | int key; 23 | uint64_t ticks; 24 | struct rte_ring rx_tx_ring; 25 | } cb_args; 26 | 27 | 28 | 29 | int arp_init(void); 30 | 31 | int pfm_arp_process_reply(struct rte_mbuf *pkt,uint16_t link_id); 32 | 33 | arp_entry_t* pfm_arp_query(pfm_ip_addr_t ip_addr); 34 | 35 | void pfm_arp_print(FILE *fp); 36 | 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /unittests/arp/pfm_comm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_COMM_H__ 2 | #define __PFM_COMM_H__ 1 3 | #include 4 | #include "pfm.h" 5 | #define MAX_LCORES 32 6 | #define MAX_LINK_COUNT 5 7 | #define LAST_LINK_ID MAX_LINK_COUNT 8 | #define MAX_KNI_PORTS 5 9 | #define MAX_LOCAL_IP_COUNT (MAX_KNI_PORTS*2) 10 | 11 | #define MBUF_COUNT 4096 12 | #define MBUF_CASHE_SIZE 128 13 | #define MBUF_PRIV_SIZE 0 14 | 15 | /* DPDK object names */ 16 | #define MBUF_NAME "MBUF" 17 | #define TX_RING_NAME "TXRING" 18 | #define RX_RING_NAME "RXRING" 19 | #define DIST_NAME "DISTNAME" 20 | 21 | #define TX_RING_SIZE 64 22 | #define RX_RING_SIZE TX_RING_SIZE 23 | #define TX_BURST_SIZE 32 24 | #define RX_BURST_SIZE TX_BURST_SIZE 25 | 26 | #define MAC_ADDR_SIZE RTE_ETHER_ADDR_LEN 27 | #define IP_ADDR_SIZE 4 28 | #define STR_IP_ADDR_SIZE 20 29 | #define DEFAULT_MTU_SIZE 1500 30 | #define DEFAULT_MIN_MTU_SIZE 68 31 | #define DEFAULT_MAX_MTU_SIZE 65535 32 | 33 | #define ARP_TABLE_SIZE 32 34 | 35 | enum { 36 | LCORE_MAIN = 0, 37 | LCORE_RXLOOP = 1, 38 | LCORE_TXLOOP = 2, 39 | LCORE_DISTRIBUTOR = 3, 40 | LCORE_WORKER = 4, 41 | LCORE_MIN_LCORE_COUNT 42 | }; 43 | 44 | #define MAX_WORKERS (MAX_LCORES - LCORE_WORKER) 45 | typedef enum 46 | { 47 | ADMSTATE_UNLOCKED, 48 | ADMSTATE_LOCKED, 49 | } admin_state_t; 50 | 51 | typedef enum 52 | { 53 | OPSSTATE_NOTCONFIGURED, 54 | OPSSTATE_ENABLED, 55 | OPSSTATE_DISABLED, 56 | OPSSTATE_FAULTY 57 | } ops_state_t; 58 | 59 | typedef struct { 60 | int kniIdx; 61 | pfm_ip_addr_t ip_addr; 62 | pfm_ip_addr_t network_mask; 63 | pfm_ip_addr_t default_gateway_ip; 64 | } local_ip_addr_t; 65 | 66 | typedef struct { 67 | int lcore_count; 68 | int kni_count; 69 | int local_ip_count; 70 | local_ip_addr_t local_ip_addr_list[MAX_LOCAL_IP_COUNT]; 71 | struct rte_mempool *mbuf_pool; 72 | struct rte_ring *rx_ring_ptr ; 73 | struct rte_ring *tx_ring_ptr ; 74 | struct rte_kni *kni_ptr; 75 | struct rte_distributor *dist_ptr; 76 | } sys_info_t; 77 | 78 | 79 | extern volatile pfm_bool_t force_quit_g; /* all loops will use this 80 | varable to determin the looping need to continue 81 | or not. By setting this varlbale to TRUE, all loops 82 | can be terminated */ 83 | extern sys_info_t sys_info_g; 84 | 85 | 86 | #endif 87 | -------------------------------------------------------------------------------- /unittests/arp/pfm_link.h: -------------------------------------------------------------------------------- 1 | #ifndef __LINK_H__ 2 | #define __LINK_H__ 1 3 | #include "pfm.h" 4 | #include "pfm_comm.h" 5 | 6 | int link_read(struct rte_mbuf *rx_pkts[],uint16_t burst_size,uint16_t *link_id); 7 | 8 | /* Application needs to implement the following callback functions */ 9 | void link_state_change_callback(int link_id, ops_state_t ops_state); 10 | void link_state_change(const int link_id,const ops_state_t desired_state); 11 | void pfm_link_list_print(FILE *fp); 12 | void pfm_link_show_print(FILE *fp, int link_id); 13 | #endif 14 | -------------------------------------------------------------------------------- /unittests/hash/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2010-2014 Intel Corporation 3 | 4 | # binary name 5 | APP = hash_unit_test.exe 6 | 7 | # all source are stored in SRCS-y 8 | SRCS-y := hash_unit_test.c 9 | 10 | # Build using pkg-config variables if possible 11 | ifeq ($(shell pkg-config --exists libdpdk && echo 0),0) 12 | 13 | all: shared 14 | .PHONY: shared static 15 | shared: build/$(APP)-shared 16 | ln -sf $(APP)-shared build/$(APP) 17 | static: build/$(APP)-static 18 | ln -sf $(APP)-static build/$(APP) 19 | 20 | PKGCONF ?= pkg-config 21 | 22 | PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) 23 | CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) 24 | CFLAGS += -DALLOW_EXPERIMENTAL_API 25 | LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) 26 | LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) 27 | 28 | build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build 29 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 30 | 31 | build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build 32 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) 33 | 34 | build: 35 | @mkdir -p $@ 36 | 37 | .PHONY: clean 38 | clean: 39 | rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared 40 | test -d build && rmdir -p build || true 41 | 42 | else # Build using legacy build system 43 | 44 | ifeq ($(RTE_SDK),) 45 | $(error "Please define RTE_SDK environment variable") 46 | endif 47 | 48 | # Default target, detect a build directory, by looking for a path with a .config 49 | RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) 50 | 51 | include $(RTE_SDK)/mk/rte.vars.mk 52 | 53 | ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),y) 54 | $(error This application can only operate in a linux environment, \ 55 | please change the definition of the RTE_TARGET environment variable) 56 | endif 57 | 58 | #CFLAGS += -O3 -g -DTRACE -DCONSLOG 59 | CFLAGS += -O3 -g -DTRACE 60 | CFLAGS += -DALLOW_EXPERIMENTAL_API 61 | CFLAGS += $(WERROR_FLAGS) 62 | 63 | include $(RTE_SDK)/mk/rte.extapp.mk 64 | endif 65 | -------------------------------------------------------------------------------- /unittests/hash/hash_unit_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | 29 | #define PFM_ARP_TABLE_ENTRIES 32 30 | #define PFM_ARP_HASH_NAME "ARP_TABLE_HASH" 31 | #define PFM_ARP_HASH_KEY_LEN 32 32 | #define HASH_SEED 26 33 | 34 | 35 | 36 | static struct rte_hash* hash_mapper; 37 | 38 | 39 | 40 | static int 41 | arp_init(void) { 42 | 43 | struct rte_hash_parameters hash_params = { 44 | .name = PFM_ARP_HASH_NAME, 45 | .entries = PFM_ARP_TABLE_ENTRIES, 46 | .reserved = 0, 47 | .key_len = PFM_ARP_HASH_KEY_LEN, 48 | .hash_func = rte_jhash, 49 | .hash_func_init_val = 0, 50 | .socket_id = (int)rte_socket_id() 51 | }; 52 | 53 | hash_mapper = rte_hash_create(&hash_params); 54 | if (hash_mapper == NULL) { 55 | printf("Error during arp init"); 56 | return -1; 57 | } 58 | printf("Hash is up\n"); 59 | return 0; 60 | } 61 | 62 | int main (int argc,char* argv[]) 63 | { 64 | int ret = rte_eal_init(argc,argv); 65 | arp_init(); 66 | int opt,key,value,pos; 67 | int table[PFM_ARP_TABLE_ENTRIES]; 68 | 69 | const void *key_ptr; 70 | void *data_ptr; 71 | uint32_t ptr = 0; 72 | uint32_t hash_count = 0; 73 | 74 | while (1) 75 | { 76 | printf("Enter operation \n1.Add key \n2.Delete key \n3.Query key\n4.Display table\n"); 77 | scanf("%d",&opt); 78 | printf("Enter key : "); 79 | scanf("%d",&key); 80 | printf("Enter value : "); 81 | scanf("%d",&value); 82 | printf("key : %d and value : %d \n",key,value); 83 | switch (opt) { 84 | case 1: 85 | printf("Adding key\n"); 86 | pos = rte_hash_lookup(hash_mapper,(void *)&key); 87 | if (pos == -ENOENT) 88 | printf("New entry\n"); 89 | if (pos >= 0) { 90 | printf("Existing key updating value\n"); 91 | table[pos] = value; 92 | } 93 | 94 | else { 95 | printf("Adding new entry\n"); 96 | pos = rte_hash_add_key(hash_mapper, 97 | (void*)&key); 98 | table[pos] = value; 99 | } 100 | break; 101 | case 2: 102 | printf("Deleting entry\n"); 103 | ret = rte_hash_del_key(hash_mapper, 104 | (void*)&key); 105 | if (ret == -ENOENT) { 106 | printf("No entry\n"); 107 | } 108 | if (ret >= 0) { 109 | table[ret] = 0; 110 | printf("\nDeleted value"); 111 | } 112 | break; 113 | 114 | case 3: 115 | printf("looking up hash table\n"); 116 | pos = rte_hash_lookup(hash_mapper, 117 | (void *)&key); 118 | if (pos == -ENOENT) 119 | printf("No entry found\n"); 120 | if (pos >= 0) { 121 | printf("\n table value is %d", 122 | table[pos]); 123 | } 124 | break; 125 | case 4: 126 | printf("Printing table\n"); 127 | hash_count = rte_hash_count(hash_mapper); 128 | ptr = 0; 129 | while ((pos = rte_hash_iterate(hash_mapper, 130 | &key_ptr, 131 | &data_ptr, 132 | &ptr)) >= 0) 133 | { 134 | printf("%d \n",table[pos]); 135 | } 136 | break; 137 | 138 | default : 139 | printf("\nInvalid option\n"); 140 | } 141 | 142 | 143 | 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /unittests/route/Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: BSD-3-Clause 2 | # Copyright(c) 2010-2014 Intel Corporation 3 | 4 | # binary name 5 | APP = route_unit_test.exe 6 | 7 | # all source are stored in SRCS-y 8 | SRCS-y := main.c \ 9 | pfm_log.c \ 10 | pfm_utils.c \ 11 | pfm_route.c 12 | 13 | # Build using pkg-config variables if possible 14 | ifeq ($(shell pkg-config --exists libdpdk && echo 0),0) 15 | 16 | all: shared 17 | .PHONY: shared static 18 | shared: build/$(APP)-shared 19 | ln -sf $(APP)-shared build/$(APP) 20 | static: build/$(APP)-static 21 | ln -sf $(APP)-static build/$(APP) 22 | 23 | PKGCONF ?= pkg-config 24 | 25 | PC_FILE := $(shell $(PKGCONF) --path libdpdk 2>/dev/null) 26 | CFLAGS += -O3 $(shell $(PKGCONF) --cflags libdpdk) 27 | CFLAGS += -DALLOW_EXPERIMENTAL_API 28 | LDFLAGS_SHARED = $(shell $(PKGCONF) --libs libdpdk) 29 | LDFLAGS_STATIC = -Wl,-Bstatic $(shell $(PKGCONF) --static --libs libdpdk) 30 | 31 | build/$(APP)-shared: $(SRCS-y) Makefile $(PC_FILE) | build 32 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_SHARED) 33 | 34 | build/$(APP)-static: $(SRCS-y) Makefile $(PC_FILE) | build 35 | $(CC) $(CFLAGS) $(SRCS-y) -o $@ $(LDFLAGS) $(LDFLAGS_STATIC) 36 | 37 | build: 38 | @mkdir -p $@ 39 | 40 | .PHONY: clean 41 | clean: 42 | rm -f build/$(APP) build/$(APP)-static build/$(APP)-shared 43 | test -d build && rmdir -p build || true 44 | 45 | else # Build using legacy build system 46 | 47 | ifeq ($(RTE_SDK),) 48 | $(error "Please define RTE_SDK environment variable") 49 | endif 50 | 51 | # Default target, detect a build directory, by looking for a path with a .config 52 | RTE_TARGET ?= $(notdir $(abspath $(dir $(firstword $(wildcard $(RTE_SDK)/*/.config))))) 53 | 54 | include $(RTE_SDK)/mk/rte.vars.mk 55 | 56 | ifneq ($(CONFIG_RTE_EXEC_ENV_LINUX),y) 57 | $(error This application can only operate in a linux environment, \ 58 | please change the definition of the RTE_TARGET environment variable) 59 | endif 60 | 61 | CFLAGS += -O3 -g -DTRACE -DCONSLOG 62 | #CFLAGS += -O3 -g -DTRACE 63 | CFLAGS += -DALLOW_EXPERIMENTAL_API 64 | CFLAGS += $(WERROR_FLAGS) 65 | 66 | include $(RTE_SDK)/mk/rte.extapp.mk 67 | endif 68 | -------------------------------------------------------------------------------- /unittests/route/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pfm_comm.h" 7 | #include "pfm_log.h" 8 | #include "pfm_route.h" 9 | #include "pfm_utils.h" 10 | 11 | 12 | 13 | int main(int argc,char* argv[]) { 14 | pfm_retval_t ret_val; 15 | int ret; 16 | int lcore_id; 17 | ipv4_addr_t ip,gw; 18 | char ipv4_addr[IP_ADDR_SIZE]; 19 | 20 | pfm_log_open("ARP-UNIT-TEST",PFM_LOG_DEBUG); 21 | ret = rte_eal_init(argc,argv); 22 | lpm_init(); 23 | ip=pfm_str2ip("129.168.1.23"); 24 | gw=pfm_str2ip("129.168.1.1"); 25 | 26 | // T.1 Simple insert to table 27 | pfm_route_add(ip, 24, gw, 7); 28 | pfm_route_print(stdout); 29 | 30 | // T.2 Update existing extry 31 | pfm_route_add(ip, 20, gw, 5); 32 | pfm_route_print(stdout); 33 | 34 | // T.3 DIfferent depth same net_mask is taken as new entry 35 | pfm_route_add(ip, 23, gw, 3); 36 | pfm_route_print(stdout); 37 | 38 | ip=pfm_str2ip("131.168.1.23"); 39 | gw=pfm_str2ip("131.168.1.1"); 40 | 41 | // T.4 Different IP and different depth taken as new entry 42 | pfm_route_add(ip, 12, gw, 3); 43 | pfm_route_print(stdout); 44 | 45 | // T.5 filling Table should fail after it crosses 32 entries 46 | ip = pfm_str2ip("192.168.22.1"); 47 | for (int i = 1;i < 32;i++) { 48 | if (i%8 == 0) { 49 | pfm_route_add(ip,i,gw,7); 50 | } 51 | else { 52 | pfm_route_add(ip,i,gw,1); 53 | } 54 | pfm_route_print(stdout); 55 | } 56 | 57 | 58 | // T.6 testing pfm_route_query 59 | ip = pfm_str2ip("129.168.1.123"); 60 | 61 | route_t* route = pfm_route_query(ip); 62 | if (route == NULL) { 63 | printf("FAILED Query T.6.a\n"); 64 | } 65 | else if (route->link_id == 7) { 66 | printf("PASSED\n"); 67 | } 68 | 69 | else { 70 | printf("FAILED Query T.6.a\n"); 71 | } 72 | 73 | ip = pfm_str2ip("9.9.9.9"); 74 | route = pfm_route_query(ip); 75 | 76 | if (route != NULL) { 77 | printf("FAILED Query T.6.b\n"); 78 | printf("%s\n",pfm_ip2str(route->net_mask,ipv4_addr)); 79 | } 80 | 81 | else { 82 | printf("PASSED\n"); 83 | } 84 | 85 | ip = pfm_str2ip("192.168.255.255"); 86 | route = pfm_route_query(ip); 87 | 88 | if (route == NULL) { 89 | printf("FAILED Query T.6.c\n"); 90 | } 91 | 92 | else if (route->link_id == 7) { 93 | printf("PASSED\n"); 94 | } 95 | 96 | else { 97 | printf("FAILED Query T.6.c\n"); 98 | } 99 | 100 | 101 | } 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /unittests/route/pfm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_H__ 2 | #define __PFM_H__ 1 3 | 4 | #include 5 | #include "pfm_log.h" 6 | 7 | 8 | typedef enum 9 | { 10 | PFM_SUCCESS, 11 | PFM_FAILED, 12 | PFM_NOT_FOUND 13 | } pfm_retval_t; 14 | 15 | typedef enum 16 | { 17 | PFM_FALSE = 0, 18 | PFM_TRUE = 1 19 | } pfm_bool_t; 20 | 21 | typedef struct { 22 | uint32_t remote_ip_addr; 23 | uint32_t remote_ip_subnet_mask; // number of bit in SubNet Mask 24 | uint16_t remote_gtp_port_num; 25 | } end_point_info_t; 26 | 27 | pfm_retval_t pfm_init(int argc, char *argv[]); 28 | pfm_retval_t pfm_end_point_add( const int link_id, 29 | const char *kni_name, 30 | const uint32_t local_ip_addr, 31 | const uint16_t local_gtp_port_num, 32 | const end_point_info_t ep[], 33 | const int ep_count); 34 | 35 | pfm_retval_t pfm_start_pkt_processing(void); 36 | 37 | void pfm_data_ind( const uint32_t local_ip, 38 | const uint16_t port_num, 39 | const uint16_t tunnel_id, 40 | struct rte_mbuf *mbuf); 41 | void pfm_data_req( const uint32_t remote_ip, 42 | const uint16_t port_num, 43 | const uint16_t tunnel_id, 44 | struct rte_mbuf *mbuf); 45 | void pfm_terminate(void); 46 | int pfm_link_open(const char *link_name); 47 | void pfm_link_close(const char *link_name); 48 | pfm_retval_t pfm_ingress_classifier_add(const int link_id, 49 | const char *kni_name, 50 | const unsigned char *local_ip_addr, 51 | const int subnet_mask_len, 52 | const int gtp_port_no); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /unittests/route/pfm_comm.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_COMM_H__ 2 | #define __PFM_COMM_H__ 1 3 | #include "pfm.h" 4 | #define MAX_LINK_COUNT 5 5 | #define LAST_LINK_ID MAX_LINK_COUNT 6 | #define MAX_KNI_PORTS 5 7 | #define MAX_LOCAL_IP_COUNT (MAX_KNI_PORTS*2) 8 | 9 | #define MBUF_COUNT 4096 10 | #define MBUF_CASHE_SIZE 128 11 | #define MBUF_PRIV_SIZE 0 12 | 13 | /* DPDK object names */ 14 | #define MBUF_NAME "MBUF" 15 | #define TX_RING_NAME "TXRING" 16 | #define RX_RING_NAME "RXRING" 17 | #define DIST_NAME "DISTNAME" 18 | 19 | #define TX_RING_SIZE 64 20 | #define RX_RING_SIZE TX_RING_SIZE 21 | #define TX_BURST_SIZE 32 22 | #define RX_BURST_SIZE TX_BURST_SIZE 23 | 24 | #define MAC_ADDR_SIZE 6 25 | #define IP_ADDR_SIZE 4 26 | #define STR_IP_ADDR_SIZE 20 27 | #define DEFAULT_MTU_SIZE 1500 28 | #define DEFAULT_MIN_MTU_SIZE 68 29 | #define DEFAULT_MAX_MTU_SIZE 65535 30 | 31 | #define ARP_TABLE_SIZE 32 32 | 33 | enum { 34 | LCORE_MAIN = 0, 35 | LCORE_RXLOOP = 1, 36 | LCORE_TXLOOP = 2, 37 | LCORE_DISTRIBUTOR = 3, 38 | LCORE_WORKER = 4, 39 | LCORE_MIN_LCORE_COUNT 40 | }; 41 | 42 | typedef enum 43 | { 44 | ADMSTATE_UNLOCKED, 45 | ADMSTATE_LOCKED, 46 | } admin_state_t; 47 | 48 | typedef enum 49 | { 50 | OPSSTATE_NOTCONFIGURED, 51 | OPSSTATE_ENABLED, 52 | OPSSTATE_DISABLED, 53 | OPSSTATE_FAULTY 54 | } ops_state_t; 55 | 56 | 57 | 58 | typedef uint32_t ipv4_addr_t ; 59 | 60 | 61 | 62 | 63 | typedef struct { 64 | int kniIdx; 65 | ipv4_addr_t ip_addr; 66 | ipv4_addr_t network_mask; 67 | ipv4_addr_t default_gateway_ip; 68 | } local_ipv4_addr_t; 69 | 70 | typedef struct { 71 | int lcore_count; 72 | int kni_count; 73 | int local_ip_count; 74 | local_ipv4_addr_t local_ip_addr_list[MAX_LOCAL_IP_COUNT]; 75 | struct rte_mempool *mbuf_pool; 76 | struct rte_ring *rx_ring_ptr ; 77 | struct rte_ring *tx_ring_ptr ; 78 | struct rte_kni *kni_ptr; 79 | struct rte_distributor *dist_ptr; 80 | } sys_info_t; 81 | 82 | 83 | extern volatile pfm_bool_t force_quit_g; /* all loops will use this 84 | varable to determin the looping need to continue 85 | or not. By setting this varlbale to TRUE, all loops 86 | can be terminated */ 87 | extern sys_info_t sys_info_g; 88 | 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /unittests/route/pfm_route.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_ROUTE_H__ 2 | #define __PFM_ROUTE_H__ 1 3 | 4 | 5 | #include 6 | #include 7 | 8 | #define PFM_ROUTE_LPM_MAX_ENTRIES 32 9 | #define PFM_ROUTE_LPM_MAX_TBL8S 8 10 | #define PFM_ROUTE_LPM_FLAGS 0 11 | #define PFM_ROUTE_LPM_NAME "PFM_ROUTE_LPM" 12 | 13 | 14 | 15 | 16 | typedef struct route_table_entry { 17 | uint8_t link_id; 18 | ipv4_addr_t net_mask; 19 | uint8_t net_mask_depth; 20 | ipv4_addr_t gateway_addr; 21 | } route_t; 22 | 23 | typedef struct route_table { 24 | struct rte_lpm *lpm_mapper; 25 | route_t entries[PFM_ROUTE_LPM_MAX_ENTRIES]; 26 | } route_table_t; 27 | 28 | 29 | 30 | /***************** 31 | * 32 | * Function to craete lpm handler using the pfm_lpm_config structure provided 33 | * @params 34 | * void 35 | * 36 | * @returns 37 | * - 0 if success, -1 on error 38 | * 39 | * 40 | * **************/ 41 | 42 | int lpm_init(void); 43 | 44 | 45 | /***************** 46 | * 47 | * 48 | * 49 | * search for entry exisiting in ROUTE table, if not add a new entry and update LPM 50 | * 51 | * @params 52 | * link_id - the linkid that is to be updated (uint16_t) 53 | * net_mask - net_mask that is to be updated (ipv4_addr_t) 54 | * net_mask_depth - depth of the net_mask to be updated (uint16_t) 55 | * gateway_addr - address of gateway to be taken (ipv4_addr_t) 56 | * 57 | * @returns 58 | * 0 if success or -error number 59 | * 60 | * 61 | *****************/ 62 | 63 | 64 | int pfm_route_add(ipv4_addr_t net_mask,uint8_t net_mask_depth,ipv4_addr_t gateway_addr,uint16_t link); 65 | 66 | 67 | /******************** 68 | * 69 | * route_query 70 | * 71 | * search for entry for given ip address and return route info 72 | * 73 | * @params 74 | * ip_addr - key to query route table (ipv4_addr_t) 75 | * 76 | * @returns 77 | * the route table entry if found, null other wise (route_t) 78 | * 79 | *********************/ 80 | 81 | route_t *pfm_route_query(ipv4_addr_t ip_addr); 82 | 83 | /********************** 84 | * 85 | * route_print 86 | * 87 | * list all the current table entrie in route table, 88 | * and print to the file stram provided 89 | * 90 | * @params 91 | * fp - File stream to print the output to (FILE *) 92 | * 93 | **********************/ 94 | 95 | void pfm_route_print(FILE *fp); 96 | 97 | #endif 98 | -------------------------------------------------------------------------------- /unittests/route/pfm_utils.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "pfm.h" 7 | #include "pfm_comm.h" 8 | #include "pfm_log.h" 9 | #include "pfm_utils.h" 10 | 11 | ipv4_addr_t pfm_str2ip(const char *ip_str) 12 | { 13 | ipv4_addr_t ipn; // IP in network order 14 | ipv4_addr_t iph; // IP in host order 15 | int ret; 16 | 17 | ret = inet_pton(AF_INET,ip_str,&ipn); 18 | if (1 != ret) 19 | { 20 | pfm_log_std_err(PFM_LOG_WARNING, 21 | "Failed to convert IP=[%s] to " 22 | "pfm_ip_addr_t format", ip_str); 23 | return 0; 24 | } 25 | iph = ntohl(ipn); 26 | return iph; 27 | } 28 | 29 | const char *pfm_ip2str(ipv4_addr_t iph,char *ip_str) 30 | { 31 | ipv4_addr_t ipn; // IP in network order 32 | 33 | ipn = htonl(iph); 34 | const char *ret = inet_ntop(AF_INET,&ipn,ip_str,STR_IP_ADDR_SIZE); 35 | if (NULL == ret) 36 | { 37 | pfm_log_std_err(PFM_LOG_ERR, 38 | "Failed to IP=[0x%0X] to string format",iph); 39 | return NULL; 40 | } 41 | return ip_str; 42 | } 43 | 44 | -------------------------------------------------------------------------------- /unittests/route/pfm_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef __PFM_UTILS_H__ 2 | #define __PFM_UTILS_H__ 1 3 | #include "pfm.h" 4 | 5 | ipv4_addr_t pfm_str2ip(const char *ip_str); 6 | const char *pfm_ip2str(ipv4_addr_t iph,char *ip_addr_str); 7 | 8 | #endif 9 | 10 | 11 | --------------------------------------------------------------------------------