uhd/host/lib/utils/prefs.cpp
Alex Williams ad2720d718 mpmd,transport,prefs: Add xport_mgr for dpdk_zero_copy
Add configuration sections to the UHD config file for NIC entries. Keys
are based on MAC addresses, and the entries beneath the section describe
which CPU and I/O thread to use for the NIC and its IPv4 address.

Make ring sizes configurable for uhd-dpdk. Ring size is now an argument
for packet buffers. Note that the maximum number of available buffers
is still determined at init!

Add ability to receive broadcasts to uhd-dpdk. This is controllable by
a boolean in the sockarg during socket creation. dpdk_zero_copy will
filter broadcast packets out.

Add dpdk_simple transport (to mirror udp_simple). This transport allows
receiving from broadcast addresses, but it only permits one outstanding
buffer at a time.

Fix IP checksum handling in UHD-DPDK.
TX checksums were not being calculated in the NIC, and in RX, the check
for IP checksums allowed values of zero (reported as none). Now packets
with bad IP checksums will be dropped.
2019-01-25 13:30:22 -08:00

125 lines
3.5 KiB
C++

//
// Copyright 2017-2018 Ettus Research, a National Instruments Company
//
// SPDX-License-Identifier: GPL-3.0+
//
#include <config.h>
#include <uhd/utils/log.hpp>
#include <uhd/utils/paths.hpp>
#include <uhdlib/utils/prefs.hpp>
#include <uhdlib/utils/paths.hpp>
#include <boost/filesystem.hpp>
#include <cstdlib>
using namespace uhd;
namespace {
constexpr char UHD_CONF_FILE_VAR[] = "UHD_CONFIG_FILE";
inline void _update_conf_file(
const std::string& path,
const std::string& config_type,
config_parser& conf_file
) {
if (not path.empty()) {
UHD_LOG_TRACE("PREFS", "Trying to load " << path);
try {
conf_file.read_file(path);
UHD_LOG_DEBUG("PREFS",
"Loaded " << config_type << " config file " << path);
} catch (...) {
// nop
}
}
}
void update_from_key(
const std::string& key, const std::string &value,
uhd::device_addr_t& user_args
) {
if (value.empty()) {
return;
}
const std::string key_str = key + "=" + value;
for (const auto& key : uhd::prefs::get_uhd_config().options(key_str)) {
user_args[key] =
uhd::prefs::get_uhd_config().get<std::string>(key_str, key);
}
}
device_addr_t get_args(
const uhd::device_addr_t& user_args,
const std::vector<std::string>& keys_to_update_from
) {
device_addr_t args;
for (const auto& key : keys_to_update_from) {
update_from_key(key, user_args.get(key, ""), args);
}
// Finally, copy over the original user args:
for (const auto& user_key : user_args.keys()) {
args[user_key] = user_args[user_key];
}
return args;
}
}
config_parser& uhd::prefs::get_uhd_config()
{
static config_parser _conf_files{};
static bool init_done = false;
if (not init_done) {
UHD_LOG_TRACE("CONF", "Initializing config file object...");
const std::string sys_conf_file = path_expandvars(UHD_SYS_CONF_FILE);
_update_conf_file(sys_conf_file, "system", _conf_files);
const std::string user_conf_file =
(boost::filesystem::path(get_app_path())
/ std::string(UHD_USER_CONF_FILE)).string();
_update_conf_file(user_conf_file, "user", _conf_files);
std::string env_conf_file;
try { // getenv into std::string can fail
if (std::getenv(UHD_CONF_FILE_VAR) != NULL) {
env_conf_file = std::string(std::getenv(UHD_CONF_FILE_VAR));
}
_update_conf_file(env_conf_file, "ENV", _conf_files);
} catch (const std::exception &) {
// nop
}
UHD_LOG_TRACE("PREFS", "Done initializing.");
}
return _conf_files;
}
device_addr_t uhd::prefs::get_usrp_args(
const uhd::device_addr_t &user_args
) {
const std::vector<std::string> keys_to_update_from = {
"type",
"product",
"serial"
};
return get_args(user_args, keys_to_update_from);
}
device_addr_t uhd::prefs::get_dpdk_args(
const uhd::device_addr_t &user_args
) {
const std::vector<std::string> keys_to_update_from = {
"use_dpdk"
};
return get_args(user_args, keys_to_update_from);
}
device_addr_t uhd::prefs::get_dpdk_nic_args(
const uhd::device_addr_t &user_args
) {
const std::vector<std::string> keys_to_update_from = {
"dpdk-mac"
};
return get_args(user_args, keys_to_update_from);
}