diff options
Diffstat (limited to 'host/lib/include/uhdlib')
| -rw-r--r-- | host/lib/include/uhdlib/transport/dpdk_common.hpp | 80 | ||||
| -rw-r--r-- | host/lib/include/uhdlib/transport/dpdk_simple.hpp | 95 | ||||
| -rw-r--r-- | host/lib/include/uhdlib/transport/uhd-dpdk.h | 33 | ||||
| -rw-r--r-- | host/lib/include/uhdlib/utils/prefs.hpp | 34 | 
4 files changed, 235 insertions, 7 deletions
diff --git a/host/lib/include/uhdlib/transport/dpdk_common.hpp b/host/lib/include/uhdlib/transport/dpdk_common.hpp new file mode 100644 index 000000000..2f320e79e --- /dev/null +++ b/host/lib/include/uhdlib/transport/dpdk_common.hpp @@ -0,0 +1,80 @@ +// +// Copyright 2018 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_DPDK_COMMON_HPP +#define INCLUDED_DPDK_COMMON_HPP + +#include <uhd/config.hpp> +#include <uhd/types/device_addr.hpp> +#include <uhd/utils/static.hpp> +#include <array> +#include <atomic> +#include <mutex> +#include <string> + +namespace uhd { namespace transport { + +class uhd_dpdk_ctx : boost::noncopyable { +public: +    UHD_SINGLETON_FCN(uhd_dpdk_ctx, get); + +    ~uhd_dpdk_ctx(void); + +    /*! +     * Initialize uhd-dpdk (and do only once) +     * \param user_args User args passed in to override config files +     */ +    void init(const device_addr_t &user_args); + +    /*! +     * Get MTU of NICs used by DPDK +     * +     * \return Number of Bytes in MTU +     */ +    size_t get_mtu(void) const; + +    /*! +     * Get port ID from provided MAC address +     * \param mac_addr MAC address +     * \param port_id Int to write ID of port corresponding to MAC address +     * \return 0 if match found, else no match +     */ +    int get_port_id(std::array<uint8_t, 6> mac_addr, unsigned int &port_id) const; + +    /*! +     * Get port ID for routing packet destined for given address +     * \param addr Destination address +     * \return port ID from routing table +     */ +    int get_route(const std::string &addr) const; + +    /*! +     * Set IPv4 address and subnet mask of given NIC port +     * Not thread-safe. Should only be written before ports are in use. +     * \param port_id NIC port ID +     * \param ipv4_addr IPv4 address to write +     * \param netmask Subnet mask identifying network number in ipv4_addr +     * \return 0 if successful, else error +     */ +    int set_ipv4_addr(unsigned int port_id, uint32_t ipv4_addr, uint32_t netmask); + +    /*! +     * \return whether init() has been called +     */ +    bool is_init_done(void) const; + +private: +    uhd_dpdk_ctx(void); + +    size_t _mtu; +    std::mutex _init_mutex; +    std::atomic<bool> _init_done; +    uhd::dict<uint32_t, unsigned int> _routes; +}; + +}} // namespace uhd::transport + +#endif /* INCLUDED_DPDK_COMMON_HPP */ diff --git a/host/lib/include/uhdlib/transport/dpdk_simple.hpp b/host/lib/include/uhdlib/transport/dpdk_simple.hpp new file mode 100644 index 000000000..62728b38d --- /dev/null +++ b/host/lib/include/uhdlib/transport/dpdk_simple.hpp @@ -0,0 +1,95 @@ +// +// Copyright 2019 Ettus Research, a National Instruments Company +// +// SPDX-License-Identifier: GPL-3.0-or-later +// + +#ifndef INCLUDED_DPDK_SIMPLE_HPP +#define INCLUDED_DPDK_SIMPLE_HPP + +#include <uhdlib/transport/dpdk_common.hpp> + +namespace uhd { namespace transport { + +class dpdk_simple : boost::noncopyable +{ +public: +    typedef boost::shared_ptr<dpdk_simple> sptr; + +    virtual ~dpdk_simple(void) = 0; + +    /*! +     * Make a new connected dpdk transport: +     * This transport is for sending and receiving +     * between this host and a single endpoint. +     * The primary usage for this transport will be control transactions. +     * +     * The address must be an ipv4 address. +     * The port must be a number. +     * +     * \param addr a string representing the destination address +     * \param port a string representing the destination port +     */ +    static sptr make_connected(struct uhd_dpdk_ctx &ctx, +        const std::string &addr, const std::string &port); + +    /*! +     * Make a new broadcasting dpdk transport: +     * This transport can send broadcast datagrams +     * and receive datagrams from multiple sources. +     * The primary usage for this transport will be to discover devices. +     * +     * The address must be an ipv4 address. +     * The port must be a number. +     * +     * \param addr a string representing the destination address +     * \param port a string representing the destination port +     */ +    static sptr make_broadcast(struct uhd_dpdk_ctx &ctx, +        const std::string &addr, const std::string &port); + +    /*! +     * Request a single send buffer of specified size. +     * +     * \param buf a pointer to place to write buffer location +     * \return the maximum length of the buffer in Bytes +     */ +    virtual size_t get_tx_buf(void** buf) = 0; + +    /*! +     * Send and release outstanding buffer +     * +     * \param number of bytes sent (releases buffer if sent) +     */ +    virtual size_t send(size_t length) = 0; + +    /*! +     * Receive a single packet. +     * Buffer provided by transport (must be freed). +     * +     * \param buf a pointer to place to write buffer location +     * \param timeout the timeout in seconds +     * \return the number of bytes received or zero on timeout +     */ +    virtual size_t recv(void **buf, double timeout = 0.1) = 0; + +    /*! +     * Return/free receive buffer +     */ +    virtual void put_rx_buf(void) = 0; + +    /*! +     * Get the last IP address as seen by recv(). +     * Only use this with the broadcast socket. +     */ +    virtual std::string get_recv_addr(void) = 0; + +    /*! +     * Get the IP address for the destination +     */ +    virtual std::string get_send_addr(void) = 0; +}; + +}} // namespace uhd::transport + +#endif /* INCLUDED_DPDK_SIMPLE_HPP */ diff --git a/host/lib/include/uhdlib/transport/uhd-dpdk.h b/host/lib/include/uhdlib/transport/uhd-dpdk.h index 8d46912bd..ae7d31383 100644 --- a/host/lib/include/uhdlib/transport/uhd-dpdk.h +++ b/host/lib/include/uhdlib/transport/uhd-dpdk.h @@ -31,12 +31,22 @@ enum uhd_dpdk_sock_type {  };  /** - * Init UHD-DPDK environment and bring up ports (link UP). - * - * Offload capabilities will be used if available + * Init UHD-DPDK environment, including DPDK's EAL. + * This will make available information about the DPDK-assigned NIC devices.   *    * @param argc passed directly to rte_eal_init()   * @param argv passed directly to rte_eal_init() + * + * @return Returns negative error code if there were issues, else 0 + */ +int uhd_dpdk_init(int argc, const char **argv); + +/** + * Start UHD-DPDK networking stack. Bring ports up (link UP). + * uhd_dpdk_init() must be called first. + * + * Offload capabilities will be used if available + *   * @param num_ports number of network interfaces to map   * @param port_thread_mapping array of num_ports entries specifying which thread   *     will drive the I/O for a given port (determined by array index) @@ -47,9 +57,8 @@ enum uhd_dpdk_sock_type {   *   * @return Returns negative error code if there were issues, else 0   */ -int uhd_dpdk_init(int argc, const char **argv, unsigned int num_ports, -                  int *port_thread_mapping, int num_mbufs, int mbuf_cache_size, -                  int mtu); +int uhd_dpdk_start(unsigned int num_ports, int *port_thread_mapping, +                   int num_mbufs, int mbuf_cache_size, int mtu);  /**   * @return Returns number of ports registered to DPDK. @@ -58,6 +67,12 @@ int uhd_dpdk_init(int argc, const char **argv, unsigned int num_ports,  int uhd_dpdk_port_count(void);  /** + * @return Returns 0 if link is down, 1 if link is up, and negative error code + *         if error occurred. + */ +int uhd_dpdk_port_link_status(unsigned int portid); + +/**   * @return Returns Ethernet MAC address of requested port   *   * @param portid ID number of network interface @@ -121,17 +136,21 @@ int uhd_dpdk_sock_close(struct uhd_dpdk_socket *sock);  /**   * Arguments for a UDP socket - * All data should be provided in network format + * All address/port data should be provided in network format   */  struct uhd_dpdk_sockarg_udp {      /*! True for TX socket, false for RX socket */      bool     is_tx; +    /*! True to filter broadcast packets, else recv */ +    bool     filter_bcast;      /*! Local udp port. This is dst_port for RX, src_port for TX */      uint16_t local_port;      /*! Remote udp port. This is dst_port for TX */      uint16_t remote_port;      /*! IPv4 address for destination (TX) */      uint32_t dst_addr; +    /*! Number of buffers in ring */ +    size_t   num_bufs;  };  /** diff --git a/host/lib/include/uhdlib/utils/prefs.hpp b/host/lib/include/uhdlib/utils/prefs.hpp index 62831a875..e528450cd 100644 --- a/host/lib/include/uhdlib/utils/prefs.hpp +++ b/host/lib/include/uhdlib/utils/prefs.hpp @@ -48,6 +48,40 @@ namespace uhd { namespace prefs {       */      uhd::device_addr_t get_usrp_args(const uhd::device_addr_t &user_args); +    /*! Convenience function to update global DPDK args with settings from +     * config files. +     * +     * Searches for a profile attached to the dpdk-conf key, like this: +     * [dpdk-conf=myconfig] +     * num_mbufs=4095 +     * mbuf_cache_size=315 +     * mtu=8000 +     * +     * \param user_args After getting the device args from the config +     *                  files, all of these key/value pairs will be applied +     *                  and will overwrite the settings from config files +     *                  if they exist. +     */ +    uhd::device_addr_t get_dpdk_args(const uhd::device_addr_t &user_args); + +    /*! Convenience function to update per-NIC DPDK args with settings from +     * config files. +     * +     * Grabs settings based on provided MAC address. Sections created like so: +     * [dpdk-mac=00:01:02:03:04:05] +     * dpdk-ipv4 = 192.168.20.1/24 +     * dpdk-io-cpu = 1 +     * +     * [dpdk-mac=00:01:02:03:04:06] +     * dpdk-ipv4 = 192.168.40.1/24 +     * dpdk-io-cpu = 1 +     * +     * \param user_args After getting the device args from the config +     *                  files, all of these key/value pairs will be applied +     *                  and will overwrite the settings from config files +     *                  if they exist. +     */ +    uhd::device_addr_t get_dpdk_nic_args(const uhd::device_addr_t &user_args);  }} /* namespace uhd::prefs */  #endif /* INCLUDED_LIBUHD_UTILS_PREFS_HPP */  | 
