Added EPS bearer id to apply_tft interface. Sending packets to the correct LCID if they match the packet filter.

master
Pedro Alvarez 6 years ago committed by Andre Puschmann
parent 657ef090a2
commit 2723aa9b12

@ -98,7 +98,8 @@ class gw_interface_nas
{ {
public: 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 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 // GW interface for RRC

@ -60,7 +60,7 @@ public:
// NAS interface // 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 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 // RRC interface
void add_mch_port(uint32_t lcid, uint32_t port); void add_mch_port(uint32_t lcid, uint32_t port);

@ -65,9 +65,10 @@ const uint8_t TCP_PROTOCOL = 0x06;
class tft_packet_filter_t class tft_packet_filter_t
{ {
public: 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); bool match(const srslte::unique_byte_buffer_t& pdu);
uint8_t eps_bearer_id;
uint8_t id; uint8_t id;
uint8_t eval_precedence; uint8_t eval_precedence;
uint16_t active_filters; uint16_t active_filters;
@ -82,7 +83,8 @@ public:
uint16_t single_remote_port; uint16_t single_remote_port;
uint16_t remote_port_range[2]; uint16_t remote_port_range[2];
uint32_t security_parameter_index; uint32_t security_parameter_index;
uint32_t type_of_service; uint8_t type_of_service;
uint8_t type_of_service_mask;
uint8_t flow_label[3]; uint8_t flow_label[3];
bool match_ip(const srslte::unique_byte_buffer_t& pdu); bool match_ip(const srslte::unique_byte_buffer_t& pdu);

@ -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; return SRSLTE_SUCCESS;
} }
int gw::apply_traffic_flow_template(uint8_t erab_id, const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft)
int gw::apply_traffic_flow_template(const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT* tft)
{ {
int err; int err;
switch (tft->tft_op_code) { 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"); gw_log->console("Adding new TFT\n");
for (int i = 0; i < tft->packet_filter_list_size; i++) { for (int i = 0; i < tft->packet_filter_list_size; i++) {
gw_log->console("New packet filter for TFT\n"); 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)); auto it = tft_filter_map.insert(std::make_pair(filter.eval_precedence, filter));
if(it.second == false){ if(it.second == false){
gw_log->error("Error inserting TFT Packet Filter\n"); gw_log->error("Error inserting TFT Packet Filter\n");
@ -319,14 +318,12 @@ void gw::run_thread()
break; break;
} }
// Check to which LCID to send the packet
uint8_t lcid = check_tft_filter_match(pdu); uint8_t lcid = check_tft_filter_match(pdu);
// Send PDU directly to PDCP // Send PDU directly to PDCP
if (pdcp->is_lcid_enabled(default_lcid)) { if (pdcp->is_lcid_enabled(lcid)) {
pdu->set_timestamp(); pdu->set_timestamp();
ul_tput_bytes += pdu->N_bytes; ul_tput_bytes += pdu->N_bytes;
pdcp->write_sdu(default_lcid, std::move(pdu), false); pdcp->write_sdu(lcid, std::move(pdu), false);
do { do {
pdu = srslte::allocate_unique_buffer(*pool); pdu = srslte::allocate_unique_buffer(*pool);
if (!pdu) { 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()){ if(!tft_filter_map.empty()){
for (std::pair<const uint16_t, tft_packet_filter_t>& filter_pair : tft_filter_map) { for (std::pair<const uint16_t, tft_packet_filter_t>& filter_pair : tft_filter_map) {
bool match = filter_pair.second.match(pdu); 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; return lcid;

@ -1164,7 +1164,7 @@ void nas::parse_activate_dedicated_eps_bearer_context_request(uint32_t lcid, uni
} }
// apply packet filters to GW // 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); send_activate_dedicated_eps_bearer_context_accept(request.proc_transaction_id, request.eps_bearer_id);
} }

@ -26,7 +26,8 @@
namespace srsue { 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), id(tft.id),
eval_precedence(tft.eval_precedence), eval_precedence(tft.eval_precedence),
active_filters(0) 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; active_filters = TYPE_OF_SERVICE_FLAG;
memcpy(&type_of_service, &tft.filter[idx], 1); memcpy(&type_of_service, &tft.filter[idx], 1);
idx += 1; idx += 1;
memcpy(&type_of_service_mask, &tft.filter[idx], 1);
idx += 1;
break; break;
//Flow label //Flow label
case FLOW_LABEL_TYPE: 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 // Check Type of Service/Traffic class
if (!match_type_of_service(pdu)) { if (!match_type_of_service(pdu)) {
printf("still not matching\n");
return false; 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)) { if (ip_pkt->version == 4 && (active_filters & TYPE_OF_SERVICE_FLAG)) {
// Check match on IPv4 packet // Check match on IPv4 packet
if (ip_pkt->tos != type_of_service) { if (ip_pkt->tos != type_of_service) {
printf("not matching!\n");
return false; return false;
} }
} else if (ip_pkt->version == 6 && (active_filters & TYPE_OF_SERVICE_FLAG)) {
// IPv6 traffic class not supported yet
return false;
} }
return true; 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 ipv6hdr* ip6_pkt = (struct ipv6hdr*)pdu->msg;
struct udphdr* udp_pkt; struct udphdr* udp_pkt;
// LOCAL_PORT_RANGE_FLAG
// SINGLE_REMOTE_PORT_FLAG
// REMOTE_PORT_RANGE_FLAG
if (ip_pkt->version == 4) { if (ip_pkt->version == 4) {
switch (ip_pkt->protocol) { switch (ip_pkt->protocol) {
case UDP_PROTOCOL: case UDP_PROTOCOL:
printf("UDP protocol\n");
udp_pkt = (struct udphdr*)&pdu->msg[ip_pkt->ihl * 4]; 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 (active_filters & SINGLE_LOCAL_PORT_FLAG) {
if (udp_pkt->source != single_local_port) { if (udp_pkt->source != single_local_port) {
return false; return false;
@ -225,10 +226,8 @@ bool tft_packet_filter_t::match_port(const srslte::unique_byte_buffer_t& pdu)
} }
break; break;
case TCP_PROTOCOL: case TCP_PROTOCOL:
printf("TCP protocol\n"); return false;
break;
default: default:
printf("Unhandled protocol\n");
return false; return false;
} }
} }

@ -143,7 +143,10 @@ class gw_dummy : public gw_interface_nas, public gw_interface_pdcp
{ {
return SRSLTE_SUCCESS; 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(uint32_t lcid, unique_byte_buffer_t pdu) {}
void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {} void write_pdu_mch(uint32_t lcid, srslte::unique_byte_buffer_t sdu) {}
}; };

@ -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}; 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); uint32_t ip_message_len2 = sizeof(ip_tst_message2);
#define EPS_BEARER_ID 6
int tft_filter_test_single_local_port() int tft_filter_test_single_local_port()
{ {
srslte::log_filter log1("TFT"); srslte::log_filter log1("TFT");
@ -102,7 +104,7 @@ int tft_filter_test_single_local_port()
packet_filter.filter_size = 3; packet_filter.filter_size = 3;
memcpy(packet_filter.filter, filter_message, 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 // Check filter
TESTASSERT(filter.match(ip_msg1)); TESTASSERT(filter.match(ip_msg1));
@ -150,7 +152,7 @@ int tft_filter_test_single_remote_port()
packet_filter.filter_size = 3; packet_filter.filter_size = 3;
memcpy(packet_filter.filter, filter_message, 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 // Check filter
TESTASSERT(filter.match(ip_msg1)); TESTASSERT(filter.match(ip_msg1));
@ -199,7 +201,7 @@ int tft_filter_test_ipv4_local_addr()
packet_filter.filter_size = filter_size; packet_filter.filter_size = filter_size;
memcpy(packet_filter.filter, filter_message, 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 // Check filter
TESTASSERT(filter.match(ip_msg1)); TESTASSERT(filter.match(ip_msg1));
@ -248,7 +250,7 @@ int tft_filter_test_ipv4_remote_addr()
packet_filter.filter_size = filter_size; packet_filter.filter_size = filter_size;
memcpy(packet_filter.filter, filter_message, 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 // Check filter
TESTASSERT(filter.match(ip_msg1)); TESTASSERT(filter.match(ip_msg1));
@ -296,7 +298,7 @@ int tft_filter_test_ipv4_tos()
packet_filter.filter_size = filter_size; packet_filter.filter_size = filter_size;
memcpy(packet_filter.filter, filter_message, 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 // Check filter
TESTASSERT(filter.match(ip_msg1)); TESTASSERT(filter.match(ip_msg1));

Loading…
Cancel
Save