5G-MAG Reference Tools - MBMS Modem
Public Member Functions | Private Attributes | List of all members
Gw Class Reference

Network gateway component. More...

#include <Gw.h>

Inheritance diagram for Gw:
Inheritance graph
Collaboration diagram for Gw:
Collaboration graph

Public Member Functions

 Gw (const libconfig::Config &cfg, Phy &phy)
 Default constructor. More...
 
virtual ~Gw ()
 Default destructor. More...
 
void init ()
 Creates the TUN interface according to params from Cfg. More...
 
void write_pdu_mch (uint32_t mch_idx, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override
 Handle a MCH PDU. More...
 
void add_mch_port (uint32_t lcid, uint32_t port) override
 
void write_pdu (uint32_t lcid, srsran::unique_byte_buffer_t pdu) override
 
int setup_if_addr (uint32_t lcid, uint8_t pdn_type, uint32_t ip_addr, uint8_t *ipv6_if_id, char *err_str) override
 
int apply_traffic_flow_template (const uint8_t &eps_bearer_id, const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT *tft) override
 
void set_test_loop_mode (const test_loop_mode_state_t mode, const uint32_t ip_pdu_delay_ms=0) override
 
int deactivate_eps_bearer (const uint32_t eps_bearer_id) override
 
bool is_running () override
 

Private Attributes

const libconfig::Config & _cfg
 
std::mutex _wr_mutex
 
int32_t _tun_fd = -1
 
Phy_phy
 

Detailed Description

Network gateway component.

Creates a TUN network interface, and writes the received MCH PDU contents out on it.

Definition at line 36 of file Gw.h.

Constructor & Destructor Documentation

◆ Gw()

Gw::Gw ( const libconfig::Config &  cfg,
Phy phy 
)
inline

Default constructor.

Parameters
cfgConfig singleton reference
phyPHY reference

Definition at line 44 of file Gw.h.

45  : _cfg(cfg)
46  , _phy(phy)
47  {}
Phy & _phy
Definition: Gw.h:79
const libconfig::Config & _cfg
Definition: Gw.h:73
static Config cfg
Global configuration object.
Definition: main.cpp:165

◆ ~Gw()

Gw::~Gw ( )
virtual

Default destructor.

Definition at line 93 of file Gw.cpp.

93  {
94  if (_tun_fd != -1) {
95  close(_tun_fd);
96  }
97 }
int32_t _tun_fd
Definition: Gw.h:78

Member Function Documentation

◆ add_mch_port()

void Gw::add_mch_port ( uint32_t  lcid,
uint32_t  port 
)
inlineoverride

Definition at line 66 of file Gw.h.

66 {};

◆ apply_traffic_flow_template()

int Gw::apply_traffic_flow_template ( const uint8_t &  eps_bearer_id,
const LIBLTE_MME_TRAFFIC_FLOW_TEMPLATE_STRUCT *  tft 
)
inlineoverride

Definition at line 69 of file Gw.h.

69 { return -1; };

◆ deactivate_eps_bearer()

int Gw::deactivate_eps_bearer ( const uint32_t  eps_bearer_id)
inlineoverride

Definition at line 72 of file Gw.h.

72 {return 0;};

◆ init()

void Gw::init ( )

Creates the TUN interface according to params from Cfg.

Definition at line 99 of file Gw.cpp.

99  {
100  char* err_str = nullptr;
101  struct ifreq ifr = {};
102 
103  _tun_fd = open("/dev/net/tun", O_RDWR | O_CLOEXEC);
104  spdlog::info("TUN file descriptor {}", _tun_fd);
105  if (0 > _tun_fd) {
106  err_str = strerror(errno);
107  spdlog::error("Failed to open TUN device {}", err_str);
108  _tun_fd = -1;
109  }
110 
111  std::string dev_name = "mbms_modem_tun";
112  if (nullptr != std::getenv("MODEM_TUN_INTERFACE")) {
113  dev_name = std::getenv("MODEM_TUN_INTERFACE");
114  }
115 
116  memset(&ifr, 0, sizeof(ifr));
117  ifr.ifr_flags = IFF_UP | IFF_TUN | IFF_NO_PI;
118  strncpy(ifr.ifr_ifrn.ifrn_name, dev_name.c_str(),
119  std::min(dev_name.length(), static_cast<size_t>(IFNAMSIZ - 1)));
120  ifr.ifr_ifrn.ifrn_name[IFNAMSIZ - 1] = 0;
121 
122  if (0 > ioctl(_tun_fd, TUNSETIFF, &ifr)) {
123  err_str = strerror(errno);
124  spdlog::error("Failed to set TUN device name {}", err_str);
125  close(_tun_fd);
126  _tun_fd = -1;
127  }
128 
129  if (0 > ioctl(_tun_fd, TUNSETPERSIST, 1)) {
130  err_str = strerror(errno);
131  spdlog::warn("Failed to set TUNSETPERSIST\n");
132  }
133 }

◆ is_running()

bool Gw::is_running ( )
inlineoverride

Definition at line 73 of file Gw.h.

73 { return true; };

◆ set_test_loop_mode()

void Gw::set_test_loop_mode ( const test_loop_mode_state_t  mode,
const uint32_t  ip_pdu_delay_ms = 0 
)
inlineoverride

Definition at line 70 of file Gw.h.

70 {};

◆ setup_if_addr()

int Gw::setup_if_addr ( uint32_t  lcid,
uint8_t  pdn_type,
uint32_t  ip_addr,
uint8_t *  ipv6_if_id,
char *  err_str 
)
inlineoverride

Definition at line 68 of file Gw.h.

68 { return -1; };

◆ write_pdu()

void Gw::write_pdu ( uint32_t  lcid,
srsran::unique_byte_buffer_t  pdu 
)
inlineoverride

Definition at line 67 of file Gw.h.

67 {};

◆ write_pdu_mch()

void Gw::write_pdu_mch ( uint32_t  mch_idx,
uint32_t  lcid,
srsran::unique_byte_buffer_t  pdu 
)
override

Handle a MCH PDU.

Verifies the contents start with an IP header, checks the IP header checksum and corrects it if necessary, and writes the packet out to the TUN interface.

Definition at line 36 of file Gw.cpp.

36  {
37  char* err_str = nullptr;
38  if (pdu->N_bytes > 2) {
39  spdlog::debug("GW: RX MCH PDU ({} B), MCH idx {}. Stack latency: {} us", pdu->N_bytes, mch_idx, pdu->get_latency_us().count());
40 
41  if (_tun_fd < 0) {
42  spdlog::warn("TUN/TAP not up - dropping gw RX message\n");
43  } else {
44  auto ip_hdr = reinterpret_cast<iphdr*>(pdu->msg);
45  if (ip_hdr->protocol == 17 /*UDP*/) {
46  auto udp_hdr = reinterpret_cast<udphdr*>(pdu->msg + 4U * ip_hdr->ihl);
47  char dest[INET6_ADDRSTRLEN] = ""; // NOLINT
48  inet_ntop(AF_INET, (const void*)&ip_hdr->daddr, dest, sizeof(dest));
49 
50  _phy.set_dest_for_lcid(mch_idx, lcid, std::string(dest) + ":" + std::to_string(ntohs(udp_hdr->dest)));
51 
52  auto ptr = reinterpret_cast<uint16_t*>(ip_hdr);
53  int32_t sum = 0;
54  sum += *ptr++; // ihl / version / dscp
55  sum += *ptr++; // total len
56  sum += *ptr++; // id
57  sum += *ptr++; // frag offset
58  sum += *ptr++; // ttl + protocol
59  ptr++; // skip checksum
60  sum += *ptr++; // src
61  sum += *ptr++; // src
62  sum += *ptr++; // dst
63  sum += *ptr; // dst
64 
65  sum = (sum >> 16) + (sum & 0xffff);
66  sum += (sum >> 16);
67 
68  uint16_t chk = ~sum;
69  if (ip_hdr->check != chk) {
70  spdlog::info("Wrong IP header checksum {}, should be {}. Correcting.", ip_hdr->check, chk);
71  ip_hdr->check = chk;
72  }
73  }
74 
75  _wr_mutex.lock();
76  int n = write(_tun_fd, pdu->msg, pdu->N_bytes);
77  _wr_mutex.unlock();
78 
79  if (n > 0 && (pdu->N_bytes != static_cast<uint32_t>(n))) {
80  spdlog::warn("DL TUN/TAP short write");
81  }
82  if (n == 0) {
83  spdlog::warn("DL TUN/TAP 0 write");
84  }
85  if (n < 0) {
86  err_str = strerror(errno);
87  spdlog::warn("DL TUN/TAP write error {}", err_str);
88  }
89  }
90  }
91 }
std::mutex _wr_mutex
Definition: Gw.h:77
void set_dest_for_lcid(uint32_t mch_idx, int lcid, std::string dest)
Definition: Phy.h:177

Member Data Documentation

◆ _cfg

const libconfig::Config& Gw::_cfg
private

Definition at line 75 of file Gw.h.

◆ _phy

Phy& Gw::_phy
private

Definition at line 79 of file Gw.h.

◆ _tun_fd

int32_t Gw::_tun_fd = -1
private

Definition at line 78 of file Gw.h.

◆ _wr_mutex

std::mutex Gw::_wr_mutex
private

Definition at line 77 of file Gw.h.


The documentation for this class was generated from the following files: