Added pcap net feature to eNodeB

This commit is contained in:
David Rupprecht 2021-03-01 11:42:17 +01:00 committed by Andre Puschmann
parent f6d8f13053
commit aef6805d03
10 changed files with 127 additions and 33 deletions

View File

@ -44,6 +44,11 @@ uint32_t mac_pcap_net::open(std::string client_ip_addr_,
return SRSLTE_ERROR;
}
logger.info("Sending MAC PCAP frames to %s:%d (from %s:%d)",
client_ip_addr_.c_str(),
client_udp_port_,
bind_addr_str.c_str(),
bind_udp_port_);
client_addr.sin_family = AF_INET;
client_addr.sin_addr.s_addr = inet_addr(client_ip_addr_.c_str());
client_addr.sin_port = htons(client_udp_port_);
@ -112,11 +117,6 @@ void mac_pcap_net::write_mac_lte_pdu_to_net(pcap_pdu_t& pdu)
return;
}
if (pdu.pdu.get()->get_headroom() < offset) {
logger.error("PDU headroom is to small for adding context buffer");
return;
}
pdu.pdu.get()->msg -= offset;
memcpy(pdu.pdu.get()->msg, buffer, offset);
pdu.pdu.get()->N_bytes += offset;
@ -128,8 +128,9 @@ void mac_pcap_net::write_mac_lte_pdu_to_net(pcap_pdu_t& pdu)
(const struct sockaddr*)&client_addr,
sizeof(client_addr));
if ((int)pdu.pdu.get()->N_bytes != bytes_sent) {
logger.error("Sending UDP packet mismatches %d != %d", pdu.pdu.get()->N_bytes, bytes_sent);
if ((int)pdu.pdu.get()->N_bytes != bytes_sent || bytes_sent < 0) {
logger.error(
"Sending UDP packet mismatches %d != %d (err %s)", pdu.pdu.get()->N_bytes, bytes_sent, strerror(errno));
}
}
@ -161,8 +162,9 @@ void mac_pcap_net::write_mac_nr_pdu_to_net(pcap_pdu_t& pdu)
(const struct sockaddr*)&client_addr,
sizeof(client_addr));
if ((int)pdu.pdu.get()->N_bytes != bytes_sent) {
logger.error("Sending UDP packet mismatches %d != %d", pdu.pdu.get()->N_bytes, bytes_sent);
if ((int)pdu.pdu.get()->N_bytes != bytes_sent || bytes_sent < 0) {
logger.error(
"Sending UDP packet mismatches %d != %d (err %s)", pdu.pdu.get()->N_bytes, bytes_sent, strerror(errno));
}
}
} // namespace srslte

View File

@ -83,11 +83,15 @@ rx_gain = 40
#####################################################################
# Packet capture configuration
#
# MAC Packets are captured to file in the compact format decoded by
# the Wireshark mac-lte-framed dissector and with DLT 147.
# To use the dissector, edit the preferences for DLT_USER to
# add an entry with DLT=147, Payload Protocol=mac-lte-framed.
# MAC-layer packets are captured to file a the compact format decoded
# by the Wireshark. For decoding, use the UDP dissector and the UDP
# heuristic dissection. Edit the preferences (Edit > Preferences >
# Protocols > DLT_USER) for DLT_USER to add an entry for DLT=149 with
# Protocol=udp. Further, enable the heuristic dissection in UDP under:
# Analyze > Enabled Protocols > MAC-LTE > mac_lte_udp and MAC-NR > mac_nr_udp
# For more information see: https://wiki.wireshark.org/MAC-LTE
# Configuring this Wireshark preferences is needed for decoding the MAC PCAP
# files as well as for the live network capture option.
#
# Please note that this setting will by default only capture MAC
# frames on dedicated channels, and not SIB. You have to build with
@ -104,6 +108,11 @@ rx_gain = 40
# s1ap_enable: Enable or disable the PCAP.
# s1ap_filename: File name where to save the PCAP.
#
# mac_net_enable: Enable MAC layer packet captures sent over the network (true/false default: false)
# bind_ip: Bind IP address for MAC network trace (default: "0.0.0.0")
# bind_port: Bind port for MAC network trace (default: 5687)
# client_ip: Client IP address for MAC network trace (default "127.0.0.1")
# client_port Client IP address for MAC network trace (default: 5847)
#####################################################################
[pcap]
enable = false
@ -111,6 +120,12 @@ filename = /tmp/enb.pcap
s1ap_enable = false
s1ap_filename = /tmp/enb_s1ap.pcap
mac_net_enable = false
bind_ip = 0.0.0.0
bind_port = 5687
client_ip = 127.0.0.1
client_port = 5847
#####################################################################
# Log configuration
#

View File

@ -26,6 +26,14 @@ typedef struct {
std::string filename;
} pcap_args_t;
typedef struct {
bool enable;
std::string client_ip;
std::string bind_ip;
uint16_t client_port;
uint16_t bind_port;
} pcap_net_args_t;
typedef struct {
bool enable;
std::string m1u_multiaddr;
@ -65,6 +73,7 @@ typedef struct {
mac_args_t mac;
s1ap_args_t s1ap;
pcap_args_t mac_pcap;
pcap_net_args_t mac_pcap_net;
pcap_args_t s1ap_pcap;
stack_log_args_t log;
embms_args_t embms;

View File

@ -27,6 +27,7 @@
#include "upper/s1ap.h"
#include "enb_stack_base.h"
#include "srslte/common/mac_pcap_net.h"
#include "srslte/interfaces/enb_interfaces.h"
#include "srslte/srslog/srslog.h"
@ -125,6 +126,11 @@ private:
srslog::basic_logger& gtpu_logger;
srslog::basic_logger& stack_logger;
// PCAP and trace option
srslte::mac_pcap mac_pcap;
srslte::mac_pcap_net mac_pcap_net;
srslte::s1ap_pcap s1ap_pcap;
// task handling
srslte::task_scheduler task_sched;
srslte::task_queue_handle enb_task_queue, gtpu_task_queue, mme_task_queue, sync_task_queue;
@ -132,14 +138,12 @@ private:
// components that layers depend on (need to be destroyed after layers)
std::unique_ptr<srslte::rx_multisocket_handler> rx_sockets;
srsenb::mac mac;
srslte::mac_pcap mac_pcap;
srsenb::rlc rlc;
srsenb::pdcp pdcp;
srsenb::rrc rrc;
srsenb::gtpu gtpu;
srsenb::s1ap s1ap;
srslte::s1ap_pcap s1ap_pcap;
srsenb::mac mac;
srsenb::rlc rlc;
srsenb::pdcp pdcp;
srsenb::rrc rrc;
srsenb::gtpu gtpu;
srsenb::s1ap s1ap;
srslte::logger* logger = nullptr;

View File

@ -17,6 +17,7 @@
#include "srsenb/hdr/stack/mac/schedulers/sched_time_rr.h"
#include "srslte/common/log.h"
#include "srslte/common/mac_pcap.h"
#include "srslte/common/mac_pcap_net.h"
#include "srslte/common/task_scheduler.h"
#include "srslte/common/threads.h"
#include "srslte/common/tti_sync_cv.h"
@ -45,6 +46,7 @@ public:
void stop();
void start_pcap(srslte::mac_pcap* pcap_);
void start_pcap_net(srslte::mac_pcap_net* pcap_net_);
/******** Interface from PHY (PHY -> MAC) ****************/
int sr_detected(uint32_t tti, uint16_t rnti) final;
@ -174,7 +176,8 @@ private:
uint8_t mtch_payload_buffer[mtch_payload_len] = {};
// pointer to MAC PCAP object
srslte::mac_pcap* pcap = nullptr;
srslte::mac_pcap* pcap = nullptr;
srslte::mac_pcap_net* pcap_net = nullptr;
// Number of rach preambles detected for a cc.
std::vector<uint32_t> detected_rachs;

View File

@ -18,6 +18,7 @@
#include "srslte/common/block_queue.h"
#include "srslte/common/log.h"
#include "srslte/common/mac_pcap.h"
#include "srslte/common/mac_pcap_net.h"
#include "srslte/interfaces/sched_interface.h"
#include "srslte/mac/pdu.h"
#include "srslte/mac/pdu_queue.h"
@ -90,9 +91,9 @@ public:
uint32_t nof_tx_harq_proc = SRSLTE_FDD_NOF_HARQ);
virtual ~ue();
void reset();
void start_pcap(srslte::mac_pcap* pcap_);
void start_pcap_net(srslte::mac_pcap_net* pcap_net_);
void set_tti(uint32_t tti);
uint16_t get_rnti() { return rnti; }
uint32_t set_ta(int ta) override;
@ -142,14 +143,15 @@ private:
uint32_t dl_pmi_counter = 0;
mac_ue_metrics_t ue_metrics = {};
srslte::mac_pcap* pcap = nullptr;
uint64_t conres_id = 0;
uint16_t rnti = 0;
uint32_t nof_prb = 0;
uint32_t last_tti = 0;
uint32_t nof_failures = 0;
int nof_rx_harq_proc = 0;
int nof_tx_harq_proc = 0;
srslte::mac_pcap* pcap = nullptr;
srslte::mac_pcap_net* pcap_net = nullptr;
uint64_t conres_id = 0;
uint16_t rnti = 0;
uint32_t nof_prb = 0;
uint32_t last_tti = 0;
uint32_t nof_failures = 0;
int nof_rx_harq_proc = 0;
int nof_tx_harq_proc = 0;
std::vector<cc_buffer_handler> cc_buffers;

View File

@ -131,6 +131,11 @@ void parse_args(all_args_t* args, int argc, char* argv[])
("pcap.filename", bpo::value<string>(&args->stack.mac_pcap.filename)->default_value("enb_mac.pcap"), "MAC layer capture filename")
("pcap.s1ap_enable", bpo::value<bool>(&args->stack.s1ap_pcap.enable)->default_value(false), "Enable S1AP packet captures for wireshark")
("pcap.s1ap_filename", bpo::value<string>(&args->stack.s1ap_pcap.filename)->default_value("enb_s1ap.pcap"), "S1AP layer capture filename")
("pcap.mac_net_enable", bpo::value<bool>(&args->stack.mac_pcap_net.enable)->default_value(false), "Enable MAC network captures")
("pcap.bind_ip", bpo::value<string>(&args->stack.mac_pcap_net.bind_ip)->default_value("0.0.0.0"), "Bind IP address for MAC network trace")
("pcap.bind_port", bpo::value<uint16_t>(&args->stack.mac_pcap_net.bind_port)->default_value(5687), "Bind port for MAC network trace")
("pcap.client_ip", bpo::value<string>(&args->stack.mac_pcap_net.client_ip)->default_value("127.0.0.1"), "Client IP address for MAC network trace")
("pcap.client_port", bpo::value<uint16_t>(&args->stack.mac_pcap_net.client_port)->default_value(5847), "Enable MAC network captures")
/* Scheduling section */
("scheduler.policy", bpo::value<string>(&args->stack.mac.sched.sched_policy)->default_value("time_pf"), "DL and UL data scheduling policy (E.g. time_rr, time_pf)")

View File

@ -109,6 +109,15 @@ int enb_stack_lte::init(const stack_args_t& args_, const rrc_cfg_t& rrc_cfg_)
mac_pcap.open(args.mac_pcap.filename.c_str());
mac.start_pcap(&mac_pcap);
}
if (args.mac_pcap_net.enable) {
mac_pcap_net.open(args.mac_pcap_net.client_ip,
args.mac_pcap_net.bind_ip,
args.mac_pcap_net.client_port,
args.mac_pcap_net.bind_port);
mac.start_pcap_net(&mac_pcap_net);
}
if (args.s1ap_pcap.enable) {
s1ap_pcap.open(args.s1ap_pcap.filename.c_str());
s1ap.start_pcap(&s1ap_pcap);
@ -182,6 +191,11 @@ void enb_stack_lte::stop_impl()
if (args.mac_pcap.enable) {
mac_pcap.close();
}
if (args.mac_pcap_net.enable) {
mac_pcap_net.close();
}
if (args.s1ap_pcap.enable) {
s1ap_pcap.close();
}

View File

@ -21,7 +21,7 @@
#include "srslte/interfaces/enb_rlc_interfaces.h"
#include "srslte/interfaces/enb_rrc_interfaces.h"
//#define WRITE_SIB_PCAP
#define WRITE_SIB_PCAP
using namespace asn1::rrc;
namespace srsenb {
@ -122,6 +122,15 @@ void mac::start_pcap(srslte::mac_pcap* pcap_)
}
}
void mac::start_pcap_net(srslte::mac_pcap_net* pcap_net_)
{
pcap_net = pcap_net_;
// Set pcap in all UEs for UL messages
for (auto& u : ue_db) {
u.second->start_pcap_net(pcap_net);
}
}
/********************************************************
*
* RLC interface
@ -460,6 +469,10 @@ uint16_t mac::allocate_ue()
ue_ptr->start_pcap(pcap);
}
if (pcap_net != nullptr) {
ue_ptr->start_pcap_net(pcap_net);
}
{
srslte::rwlock_write_guard lock(rwlock);
ue_db[rnti] = std::move(ue_ptr);
@ -613,6 +626,10 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list)
pcap->write_dl_crnti(
dl_sched_res->pdsch[n].data[tb], sched_result.data[i].tbs[tb], rnti, true, tti_tx_dl, enb_cc_idx);
}
if (pcap_net) {
pcap_net->write_dl_crnti(
dl_sched_res->pdsch[n].data[tb], sched_result.data[i].tbs[tb], rnti, true, tti_tx_dl, enb_cc_idx);
}
} else {
/* TB not enabled OR no data to send: set pointers to NULL */
dl_sched_res->pdsch[n].data[tb] = nullptr;
@ -657,7 +674,14 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list)
tti_tx_dl,
enb_cc_idx);
}
if (pcap_net) {
pcap_net->write_dl_ranti(dl_sched_res->pdsch[n].data[0],
sched_result.rar[i].tbs,
dl_sched_res->pdsch[n].dci.rnti,
true,
tti_tx_dl,
enb_cc_idx);
}
n++;
}
@ -675,6 +699,10 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list)
if (pcap) {
pcap->write_dl_sirnti(dl_sched_res->pdsch[n].data[0], sched_result.bc[i].tbs, true, tti_tx_dl, enb_cc_idx);
}
if (pcap_net) {
pcap_net->write_dl_sirnti(
dl_sched_res->pdsch[n].data[0], sched_result.bc[i].tbs, true, tti_tx_dl, enb_cc_idx);
}
#endif
} else {
dl_sched_res->pdsch[n].softbuffer_tx[0] = &common_buffers[enb_cc_idx].pcch_softbuffer_tx;
@ -684,6 +712,9 @@ int mac::get_dl_sched(uint32_t tti_tx_dl, dl_sched_list_t& dl_sched_res_list)
if (pcap) {
pcap->write_dl_pch(dl_sched_res->pdsch[n].data[0], sched_result.bc[i].tbs, true, tti_tx_dl, enb_cc_idx);
}
if (pcap_net) {
pcap_net->write_dl_pch(dl_sched_res->pdsch[n].data[0], sched_result.bc[i].tbs, true, tti_tx_dl, enb_cc_idx);
}
}
n++;

View File

@ -147,6 +147,11 @@ void ue::reset()
}
}
void ue::start_pcap_net(srslte::mac_pcap_net* pcap_net_)
{
pcap_net = pcap_net_;
}
void ue::start_pcap(srslte::mac_pcap* pcap_)
{
pcap = pcap_;
@ -256,6 +261,10 @@ void ue::process_pdu(uint8_t* pdu, uint32_t nof_bytes, srslte::pdu_queue::channe
pcap->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti, UL_CC_IDX);
}
if (pcap_net) {
pcap_net->write_ul_crnti(pdu, nof_bytes, rnti, true, last_tti, UL_CC_IDX);
}
pdus.deallocate(pdu);
uint32_t lcid_most_data = 0;