diff --git a/lib/include/srslte/interfaces/ue_interfaces.h b/lib/include/srslte/interfaces/ue_interfaces.h index 42f78794b..0891ce06c 100644 --- a/lib/include/srslte/interfaces/ue_interfaces.h +++ b/lib/include/srslte/interfaces/ue_interfaces.h @@ -98,7 +98,8 @@ class gw_interface_nas { public: virtual int setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_id, char* err_str) = 0; - virtual int apply_traffic_flow_template(const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) = 0; + virtual int apply_traffic_flow_template(uint8_t eps_bearer_id, + const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) = 0; }; // GW interface for RRC diff --git a/srsue/hdr/stack/upper/gw.h b/srsue/hdr/stack/upper/gw.h index 86f23ddf9..39b16252a 100644 --- a/srsue/hdr/stack/upper/gw.h +++ b/srsue/hdr/stack/upper/gw.h @@ -60,7 +60,7 @@ public: // NAS interface int setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t* ipv6_if_addr, char* err_str); - int apply_traffic_flow_template(const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft); + int apply_traffic_flow_template(uint8_t eps_bearer_id, const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft); // RRC interface void add_mch_port(uint32_t lcid, uint32_t port); diff --git a/srsue/hdr/stack/upper/tft_packet_filter.h b/srsue/hdr/stack/upper/tft_packet_filter.h index 8aebcd926..26648b017 100644 --- a/srsue/hdr/stack/upper/tft_packet_filter.h +++ b/srsue/hdr/stack/upper/tft_packet_filter.h @@ -65,9 +65,10 @@ const uint8_t TCP_PROTOCOL = 0x06; class tft_packet_filter_t { public: - tft_packet_filter_t(const LIBLTE_MME_PACKET_FILTER_STRUCT& tft); + tft_packet_filter_t(uint8_t eps_bearer_id, const LIBLTE_MME_PACKET_FILTER_STRUCT& tft); bool match(const srslte::unique_byte_buffer_t& pdu); + uint8_t eps_bearer_id; uint8_t id; uint8_t eval_precedence; uint16_t active_filters; @@ -82,8 +83,9 @@ public: uint16_t single_remote_port; uint16_t remote_port_range[2]; uint32_t security_parameter_index; - uint32_t type_of_service; - uint8_t flow_label[3]; + uint8_t type_of_service; + uint8_t type_of_service_mask; + uint8_t flow_label[3]; bool match_ip(const srslte::unique_byte_buffer_t& pdu); bool match_protocol(const srslte::unique_byte_buffer_t& pdu); diff --git a/srsue/src/stack/upper/gw.cc b/srsue/src/stack/upper/gw.cc index 1f6fba9d6..48e20b3c1 100644 --- a/srsue/src/stack/upper/gw.cc +++ b/srsue/src/stack/upper/gw.cc @@ -219,8 +219,7 @@ int gw::setup_if_addr(uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t return SRSLTE_SUCCESS; } - -int gw::apply_traffic_flow_template(const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) +int gw::apply_traffic_flow_template(uint8_t erab_id, const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) { int err; switch (tft->tft_op_code) { @@ -228,7 +227,7 @@ int gw::apply_traffic_flow_template(const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUC gw_log->console("Adding new TFT\n"); for (int i = 0; i < tft->packet_filter_list_size; i++) { gw_log->console("New packet filter for TFT\n"); - tft_packet_filter_t filter(tft->packet_filter_list[i]); + tft_packet_filter_t filter(erab_id, tft->packet_filter_list[i]); auto it = tft_filter_map.insert(std::make_pair(filter.eval_precedence, filter)); if(it.second == false){ gw_log->error("Error inserting TFT Packet Filter\n"); @@ -319,14 +318,12 @@ void gw::run_thread() break; } - // Check to which LCID to send the packet uint8_t lcid = check_tft_filter_match(pdu); - // Send PDU directly to PDCP - if (pdcp->is_lcid_enabled(default_lcid)) { + if (pdcp->is_lcid_enabled(lcid)) { pdu->set_timestamp(); ul_tput_bytes += pdu->N_bytes; - pdcp->write_sdu(default_lcid, std::move(pdu), false); + pdcp->write_sdu(lcid, std::move(pdu), false); do { pdu = srslte::allocate_unique_buffer(*pool); if (!pdu) { @@ -359,7 +356,11 @@ uint8_t gw::check_tft_filter_match(const srslte::unique_byte_buffer_t& pdu) { if(!tft_filter_map.empty()){ for (std::pair& filter_pair : tft_filter_map) { bool match = filter_pair.second.match(pdu); - gw_log->console("Found filter match\n"); + if (match) { + lcid = filter_pair.second.eps_bearer_id - 2; + gw_log->console("Found filter match -- EPS bearer Id %d, LCID %d\n", filter_pair.second.eps_bearer_id, lcid); + break; + } } } return lcid; diff --git a/srsue/src/stack/upper/nas.cc b/srsue/src/stack/upper/nas.cc index a75450cca..e2c7caa60 100644 --- a/srsue/src/stack/upper/nas.cc +++ b/srsue/src/stack/upper/nas.cc @@ -1164,7 +1164,7 @@ void nas::parse_activate_dedicated_eps_bearer_context_request(uint32_t lcid, uni } // apply packet filters to GW - gw->apply_traffic_flow_template(tft); + gw->apply_traffic_flow_template(request.eps_bearer_id, tft); send_activate_dedicated_eps_bearer_context_accept(request.proc_transaction_id, request.eps_bearer_id); } diff --git a/srsue/src/stack/upper/tft_packet_filter.cc b/srsue/src/stack/upper/tft_packet_filter.cc index b56214c6c..1ce7fdd90 100644 --- a/srsue/src/stack/upper/tft_packet_filter.cc +++ b/srsue/src/stack/upper/tft_packet_filter.cc @@ -26,7 +26,8 @@ namespace srsue { -tft_packet_filter_t::tft_packet_filter_t(const LIBLTE_MME_PACKET_FILTER_STRUCT& tft) : +tft_packet_filter_t::tft_packet_filter_t(uint8_t eps_bearer_id, const LIBLTE_MME_PACKET_FILTER_STRUCT& tft) : + eps_bearer_id(eps_bearer_id), id(tft.id), eval_precedence(tft.eval_precedence), active_filters(0) @@ -77,6 +78,8 @@ tft_packet_filter_t::tft_packet_filter_t(const LIBLTE_MME_PACKET_FILTER_STRUCT& active_filters = TYPE_OF_SERVICE_FLAG; memcpy(&type_of_service, &tft.filter[idx], 1); idx += 1; + memcpy(&type_of_service_mask, &tft.filter[idx], 1); + idx += 1; break; //Flow label case FLOW_LABEL_TYPE: @@ -113,6 +116,7 @@ bool tft_packet_filter_t::match(const srslte::unique_byte_buffer_t& pdu) // Check Type of Service/Traffic class if (!match_type_of_service(pdu)) { + printf("still not matching\n"); return false; } @@ -177,8 +181,12 @@ bool tft_packet_filter_t::match_type_of_service(const srslte::unique_byte_buffer if (ip_pkt->version == 4 && (active_filters & TYPE_OF_SERVICE_FLAG)) { // Check match on IPv4 packet if (ip_pkt->tos != type_of_service) { + printf("not matching!\n"); return false; } + } else if (ip_pkt->version == 6 && (active_filters & TYPE_OF_SERVICE_FLAG)) { + // IPv6 traffic class not supported yet + return false; } return true; } @@ -202,17 +210,10 @@ bool tft_packet_filter_t::match_port(const srslte::unique_byte_buffer_t& pdu) struct ipv6hdr* ip6_pkt = (struct ipv6hdr*)pdu->msg; struct udphdr* udp_pkt; - // LOCAL_PORT_RANGE_FLAG - // SINGLE_REMOTE_PORT_FLAG - // REMOTE_PORT_RANGE_FLAG - if (ip_pkt->version == 4) { switch (ip_pkt->protocol) { case UDP_PROTOCOL: - printf("UDP protocol\n"); udp_pkt = (struct udphdr*)&pdu->msg[ip_pkt->ihl * 4]; - printf("%d\n", ntohs(udp_pkt->source)); - printf("%d\n", ntohs(udp_pkt->dest)); if (active_filters & SINGLE_LOCAL_PORT_FLAG) { if (udp_pkt->source != single_local_port) { return false; @@ -225,10 +226,8 @@ bool tft_packet_filter_t::match_port(const srslte::unique_byte_buffer_t& pdu) } break; case TCP_PROTOCOL: - printf("TCP protocol\n"); - break; + return false; default: - printf("Unhandled protocol\n"); return false; } } diff --git a/srsue/test/upper/nas_test.cc b/srsue/test/upper/nas_test.cc index 16c6a846e..7f6452b2a 100644 --- a/srsue/test/upper/nas_test.cc +++ b/srsue/test/upper/nas_test.cc @@ -143,7 +143,10 @@ class gw_dummy : public gw_interface_nas, public gw_interface_pdcp { return SRSLTE_SUCCESS; } - int apply_traffic_flow_template(const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) { return SRSLTE_SUCCESS; } + int apply_traffic_flow_template(uint8_t eps_bearer_id, const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft) + { + return SRSLTE_SUCCESS; + } void write_pdu(uint32_t lcid, unique_byte_buffer_t pdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {} }; diff --git a/srsue/test/upper/tft_test.cc b/srsue/test/upper/tft_test.cc index c30007baf..880e376ee 100644 --- a/srsue/test/upper/tft_test.cc +++ b/srsue/test/upper/tft_test.cc @@ -63,6 +63,8 @@ uint8_t ip_tst_message2[] = { 0x88, 0x29, 0x60, 0x02, 0xde, 0x41, 0x11, 0xc2, 0xaa, 0x5e, 0x9e, 0x27, 0x74, 0xa5, 0xd3, 0x19}; uint32_t ip_message_len2 = sizeof(ip_tst_message2); +#define EPS_BEARER_ID 6 + int tft_filter_test_single_local_port() { srslte::log_filter log1("TFT"); @@ -102,7 +104,7 @@ int tft_filter_test_single_local_port() packet_filter.filter_size = 3; memcpy(packet_filter.filter, filter_message, 3); - srsue::tft_packet_filter_t filter(packet_filter); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, packet_filter); // Check filter TESTASSERT(filter.match(ip_msg1)); @@ -150,7 +152,7 @@ int tft_filter_test_single_remote_port() packet_filter.filter_size = 3; memcpy(packet_filter.filter, filter_message, 3); - srsue::tft_packet_filter_t filter(packet_filter); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, packet_filter); // Check filter TESTASSERT(filter.match(ip_msg1)); @@ -199,7 +201,7 @@ int tft_filter_test_ipv4_local_addr() packet_filter.filter_size = filter_size; memcpy(packet_filter.filter, filter_message, filter_size); - srsue::tft_packet_filter_t filter(packet_filter); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, packet_filter); // Check filter TESTASSERT(filter.match(ip_msg1)); @@ -248,7 +250,7 @@ int tft_filter_test_ipv4_remote_addr() packet_filter.filter_size = filter_size; memcpy(packet_filter.filter, filter_message, filter_size); - srsue::tft_packet_filter_t filter(packet_filter); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, packet_filter); // Check filter TESTASSERT(filter.match(ip_msg1)); @@ -296,7 +298,7 @@ int tft_filter_test_ipv4_tos() packet_filter.filter_size = filter_size; memcpy(packet_filter.filter, filter_message, filter_size); - srsue::tft_packet_filter_t filter(packet_filter); + srsue::tft_packet_filter_t filter(EPS_BEARER_ID, packet_filter); // Check filter TESTASSERT(filter.match(ip_msg1));