22 #include <arpa/inet.h>
24 #include <linux/if_tun.h>
26 #include <netinet/ip.h>
27 #include <netinet/udp.h>
28 #include <sys/ioctl.h>
29 #include <sys/socket.h>
34 #include "spdlog/spdlog.h"
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());
42 spdlog::warn(
"TUN/TAP not up - dropping gw RX message\n");
44 auto ip_hdr =
reinterpret_cast<iphdr*
>(pdu->msg);
45 if (ip_hdr->protocol == 17 ) {
46 auto udp_hdr =
reinterpret_cast<udphdr*
>(pdu->msg + 4U * ip_hdr->ihl);
47 char dest[INET6_ADDRSTRLEN] =
"";
48 inet_ntop(AF_INET, (
const void*)&ip_hdr->daddr, dest,
sizeof(dest));
50 _phy.
set_dest_for_lcid(mch_idx, lcid, std::string(dest) +
":" + std::to_string(ntohs(udp_hdr->dest)));
52 auto ptr =
reinterpret_cast<uint16_t*
>(ip_hdr);
65 sum = (sum >> 16) + (sum & 0xffff);
69 if (ip_hdr->check != chk) {
70 spdlog::info(
"Wrong IP header checksum {}, should be {}. Correcting.", ip_hdr->check, chk);
76 int n = write(
_tun_fd, pdu->msg, pdu->N_bytes);
79 if (n > 0 && (pdu->N_bytes !=
static_cast<uint32_t
>(n))) {
80 spdlog::warn(
"DL TUN/TAP short write");
83 spdlog::warn(
"DL TUN/TAP 0 write");
86 err_str = strerror(errno);
87 spdlog::warn(
"DL TUN/TAP write error {}", err_str);
100 char* err_str =
nullptr;
101 struct ifreq ifr = {};
103 _tun_fd = open(
"/dev/net/tun", O_RDWR | O_CLOEXEC);
104 spdlog::info(
"TUN file descriptor {}",
_tun_fd);
106 err_str = strerror(errno);
107 spdlog::error(
"Failed to open TUN device {}", err_str);
111 std::string dev_name =
"mbms_modem_tun";
112 if (
nullptr != std::getenv(
"MODEM_TUN_INTERFACE")) {
113 dev_name = std::getenv(
"MODEM_TUN_INTERFACE");
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;
122 if (0 > ioctl(
_tun_fd, TUNSETIFF, &ifr)) {
123 err_str = strerror(errno);
124 spdlog::error(
"Failed to set TUN device name {}", err_str);
129 if (0 > ioctl(
_tun_fd, TUNSETPERSIST, 1)) {
130 err_str = strerror(errno);
131 spdlog::warn(
"Failed to set TUNSETPERSIST\n");
virtual ~Gw()
Default destructor.
void write_pdu_mch(uint32_t mch_idx, uint32_t lcid, srsran::unique_byte_buffer_t pdu) override
Handle a MCH PDU.
void init()
Creates the TUN interface according to params from Cfg.
void set_dest_for_lcid(uint32_t mch_idx, int lcid, std::string dest)