LCOV - code coverage report
Current view: top level - root/contrail/vrouter/include - vr_dpdk.h (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 16 24 66.7 %
Date: 2026-08-03 02:19:58 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (C) 2014 Semihalf.
       3             :  *
       4             :  * This program is free software; you can redistribute it and/or
       5             :  * modify it under the terms of the GNU General Public License as
       6             :  * published by the Free Software Foundation version 2.
       7             :  *
       8             :  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
       9             :  * kind, whether express or implied; without even the implied warranty
      10             :  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      11             :  * GNU General Public License for more details.
      12             :  *
      13             :  * vr_dpdk.h -- vRouter/DPDK definitions
      14             :  *
      15             :  */
      16             : 
      17             : #ifndef _VR_DPDK_H_
      18             : #define _VR_DPDK_H_
      19             : 
      20             : #include "vr_os.h"
      21             : #include "vr_dpdk_compat.h"
      22             : #include "vr_interface.h"
      23             : #include "vr_packet.h"
      24             : #include "vr_fragment.h"
      25             : #include "vr_cpuid.h"
      26             : 
      27             : #include <sys/queue.h>
      28             : 
      29             : #include <urcu-qsbr.h>
      30             : 
      31             : #include <rte_config.h>
      32             : #include <rte_port.h>
      33             : #include <rte_ip.h>
      34             : #include <rte_port_ring.h>
      35             : #include <rte_ethdev.h>
      36             : #include <rte_spinlock.h>
      37             : 
      38             : #ifdef PKT_RX_VLAN_PKT
      39             : #define PKT_RX_VLAN PKT_RX_VLAN_PKT
      40             : #endif
      41             : 
      42             : #if (RTE_VERSION < RTE_VERSION_NUM(19, 11, 0, 0))
      43             :      #error "vRouter needs atleast DPDK version 19.11 to start"
      44             : #endif
      45             : 
      46             : extern struct vr_interface_stats *vif_get_stats(struct vr_interface *,
      47             :         unsigned short);
      48             : extern int dpdk_vlan_forwarding_if_add(void);
      49             : extern unsigned int vr_flow_hold_limit;
      50             : extern int no_huge_set;
      51             : extern unsigned vr_packet_sz;
      52             : 
      53             : /*
      54             :  * Use RTE_LOG_DEBUG to enable debug logs.
      55             :  * See more debug options below.
      56             :  */
      57             : #undef RTE_LOG_LEVEL
      58             : #ifdef COMPILE_DEBUG_LOGS
      59             : #define RTE_LOG_LEVEL               RTE_LOG_DEBUG
      60             : #else
      61             : #define RTE_LOG_LEVEL               RTE_LOG_INFO
      62             : #endif
      63             : 
      64             : /*
      65             :  * By default all the logtypes are enabled.
      66             :  * Use VR_DPDK_LOGTYPE_DISABLE option below to disable some of the types.
      67             :  */
      68             : #define RTE_LOGTYPE_VROUTER         RTE_LOGTYPE_USER1
      69             : #define RTE_LOGTYPE_USOCK           RTE_LOGTYPE_USER2
      70             : #define RTE_LOGTYPE_UVHOST          RTE_LOGTYPE_USER3
      71             : #define RTE_LOGTYPE_DPCORE          RTE_LOGTYPE_USER4
      72             : #define RTE_LOGTYPE_OFFLOAD_PACKET  RTE_LOGTYPE_USER5
      73             : /* Disable the rest (undefined) logtypes */
      74             : #define VR_DPDK_LOGTYPE_DISABLE     (RTE_LOGTYPE_USER6 | \
      75             :                                      RTE_LOGTYPE_USER7 | RTE_LOGTYPE_USER8)
      76             : 
      77             : /*
      78             :  * Debug options:
      79             :  *
      80             : #define RTE_LOG_LEVEL               RTE_LOG_DEBUG
      81             : #define VR_DPDK_LOGTYPE_DISABLE     (RTE_LOGTYPE_USOCK | RTE_LOGTYPE_UVHOST)
      82             : #define VR_DPDK_NETLINK_DEBUG
      83             : #define VR_DPDK_NETLINK_PKT_DUMP
      84             : #define VR_DPDK_USOCK_DUMP
      85             : #define VR_DPDK_RX_PKT_DUMP
      86             : #define VR_DPDK_TX_PKT_DUMP
      87             : #define VR_DPDK_PKT_DUMP_VIF_FILTER(vif) (vif->vif_type == VIF_TYPE_AGENT \
      88             :                                         || vif->vif_type == VIF_TYPE_VIRTUAL)
      89             :  */
      90             : 
      91             : #define VR_MAX_CPUS_DPDK            256
      92             : /* Default lcore mask. Used only when sched_getaffinity() is failed */
      93             : #define VR_DPDK_DEF_LCORE_MASK      0xf
      94             : /* Default memory size to allocate at startup (in MBs) */
      95             : #define VR_DPDK_DEF_MEM             "1024"
      96             : /* Number of memory channels to use */
      97             : #define VR_DPDK_MAX_MEMCHANNELS     "4"
      98             : /* Use UDP source port hashing */
      99             : #define VR_DPDK_USE_MPLS_UDP_ECMP   true
     100             : /* Use hardware filtering (Flow Director) */
     101             : #define VR_DPDK_USE_HW_FILTERING    false
     102             : /* KNI generates random MACs for e1000e NICs, so we need this
     103             :  * option enabled for the development on servers with those NICs */
     104             : #define VR_DPDK_ENABLE_PROMISC      false
     105             : /* Maximum number of hardware RX queues to use for RSS and filtering
     106             :  * (limited by NIC and number of per queue TX/RX descriptors) */
     107             : #define VR_DPDK_MAX_NB_RX_QUEUES    16
     108             : /* Maximum number of hardware TX queues to use (limited by the number of lcores) */
     109             : #define VR_DPDK_MAX_NB_TX_QUEUES    64
     110             : /* bnxt NIC only supports 8 TX queues */
     111             : #define VR_DPDK_MAX_NB_TX_Q_BNXT    8
     112             : /* bnxt and enic only support 9022 size jumbo frames */
     113             : #define VT_DPDK_MAX_RX_PKT_LEN_9022 9022
     114             : /*
     115             :  * Special value for number of queues to indicate that each
     116             :  * packet forwarding core should be assigned one queue
     117             :  */
     118             : #define VR_DPDK_ONE_QUEUE_PER_CORE  ((uint16_t)-1)
     119             : /* Maximum number of hardware RX queues to use for RSS (limited by the number of lcores) */
     120             : #define VR_DPDK_MAX_NB_RSS_QUEUES   16
     121             : /* Maximum number of bond members per ethernet device */
     122             : #define VR_DPDK_BOND_MAX_SLAVES     6
     123             : /* Maximum RETA table size */
     124             : #define VR_DPDK_MAX_RETA_SIZE       ETH_RSS_RETA_SIZE_512
     125             : #define VR_DPDK_MAX_RETA_ENTRIES    (VR_DPDK_MAX_RETA_SIZE/RTE_RETA_GROUP_SIZE)
     126             : /* Number of hardware RX ring descriptors per queue */
     127             : #define VR_DPDK_NB_RXD              128
     128             : /* Number of hardware TX ring descriptors per queue */
     129             : #define VR_DPDK_NB_TXD              128
     130             : /* Offset to MPLS label for hardware filtering (in 16-bit word units) */
     131             : #define VR_DPDK_MPLS_OFFSET         ((VR_ETHER_HLEN             \
     132             :                                     + sizeof(struct vr_ip)      \
     133             :                                     + sizeof(struct vr_udp))/2)
     134             : /* Maximum number of rings per lcore (maximum is VR_MAX_INTERFACES*VR_MAX_CPUS_DPDK) */
     135             : #define VR_DPDK_MAX_RINGS           (VR_MAX_INTERFACES*2)
     136             : /* Maximum number of bond interfaces per lcore */
     137             : #define VR_DPDK_MAX_BONDS           2
     138             : /* Max size of a single packet used by default */
     139             : #define VR_DEF_MAX_PACKET_SZ        (9 * 1024)
     140             : /* check availability of enough lcores */
     141             : #if (RTE_MAX_LCORE < 256)
     142             : #error "vrouter needs to have support 256 lcores for AMD processors"
     143             : #endif
     144             : /* Number of bytes needed for each mbuf header */
     145             : #define VR_DPDK_MBUF_HDR_SZ         (sizeof(struct rte_mbuf)   \
     146             :                                     + sizeof(struct vr_packet) \
     147             :                                     + RTE_PKTMBUF_HEADROOM)
     148             : /* Size of direc mbuf used for fragmentation. It needs a headroom as it holds
     149             :  * the IP headers of the fragments and we have to prepend an outer (tunnel)
     150             :  * header. */
     151             : #define VR_DPDK_FRAG_DIRECT_MBUF_SZ     (sizeof(struct rte_mbuf)    \
     152             :                                          + 2*RTE_PKTMBUF_HEADROOM)
     153             : /* Size of indirect mbufs used for fragmentation. These mbufs holds only a
     154             :  * pointer to the data in other mbufs, thus they don't need any additional
     155             :  * buffer size. */
     156             : #define VR_DPDK_FRAG_INDIRECT_MBUF_SZ   (sizeof(struct rte_mbuf))
     157             : /* How many packets to read/write from/to queue in one go */
     158             : #define VR_DPDK_RX_BURST_SZ         32
     159             : #define VR_DPDK_TX_BURST_SZ         32
     160             : /* Default Number of mbufs in RSS mempool */
     161             : #define VR_DEF_MEMPOOL_SZ           (16 * 1024)
     162             : /* How many objects (mbufs) to keep in per-lcore RSS mempool cache */
     163             : #define VR_DPDK_RSS_MEMPOOL_CACHE_SZ    (VR_DPDK_RX_BURST_SZ*8)
     164             : /* Number of mbufs in FRAG_DIRECT mempool */
     165             : #define VR_DPDK_FRAG_DIRECT_MEMPOOL_SZ     4096
     166             : /* How many objects (mbufs) to keep in per-lcore FRAG_DIRECT mempool cache */
     167             : #define VR_DPDK_FRAG_DIRECT_MEMPOOL_CACHE_SZ    (VR_DPDK_RX_BURST_SZ*8)
     168             : /* Number of mbufs in FRAG_INDIRECT mempool */
     169             : #define VR_DPDK_FRAG_INDIRECT_MEMPOOL_SZ     4096
     170             : /* How many objects (mbufs) to keep in per-lcore FRAG_INDIRECT mempool cache */
     171             : #define VR_DPDK_FRAG_INDIRECT_MEMPOOL_CACHE_SZ    (VR_DPDK_RX_BURST_SZ*8)
     172             : /* Number of VM mempools */
     173             : #define VR_DPDK_MAX_VM_MEMPOOLS     (VR_DPDK_MAX_NB_RX_QUEUES*2)
     174             : /* Number of mbufs in VM mempool */
     175             : #define VR_DPDK_VM_MEMPOOL_SZ       1024
     176             : /* How many objects (mbufs) to keep in per-lcore VM mempool cache */
     177             : #define VR_DPDK_VM_MEMPOOL_CACHE_SZ (VR_DPDK_RX_BURST_SZ*8)
     178             : /* Number of mbufs in TX rings (like ring to push, socket, VLAN rings etc */
     179             : #define VR_DPDK_TX_RING_SZ          (VR_DPDK_TX_BURST_SZ*32)
     180             : /* RX ring minimum number of pointers to transfer (cache line / size of ptr) */
     181             : #define VR_DPDK_RX_RING_CHUNK_SZ    1
     182             : /* Number of mbufs in lcore RX ring (we retry in case enqueue fails) */
     183             : #define VR_DPDK_RX_RING_SZ          1024
     184             : /* Number of retries to enqueue packets */
     185             : #define VR_DPDK_RETRY_NUM           1
     186             : /* Delay between retries */
     187             : #define VR_DPDK_RETRY_US            15
     188             : /* Use timer to measure flushes (slower, but should improve latency) */
     189             : #define VR_DPDK_USE_TIMER           false
     190             : /* TX flush timeout (in loops or US if USE_TIMER defined) */
     191             : #define VR_DPDK_TX_FLUSH_LOOPS      16
     192             : /* TX idle timeout - if packets are not sent to a VM for this many
     193             :  * forwarding loops, its TX queue can be flushed if it is not
     194             :  * empty (to reduce latency).
     195             :  */
     196             : #define VR_DPDK_TX_IDLE_LOOPS       5
     197             : #define VR_DPDK_TX_FLUSH_US         100
     198             : /*
     199             :  * Bond TX timeout (in ms)
     200             :  * Receive and transmit functions must be invoked on bonded
     201             :  * interface at least 10 times per second or LACP will not
     202             :  * work correctly
     203             :  */
     204             : #define VR_DPDK_BOND_TX_MS          100
     205             : /* Sleep time in US if there are no queues to poll */
     206             : #define VR_DPDK_SLEEP_NO_QUEUES_US  10000
     207             : /* Sleep (in US) or yield if no packets received (use 0 to disable) */
     208             : #define VR_DPDK_SLEEP_NO_PACKETS_US 0
     209             : #define VR_DPDK_YIELD_NO_PACKETS    1
     210             : /* Sleep (in US) no packets received on any TAP devs (use 0 to disable) */
     211             : #define VR_DPDK_TAPDEV_SLEEP_NO_PACKETS_US 500
     212             : /* Timers handling periodicity in US */
     213             : #define VR_DPDK_SLEEP_TIMER_US      100
     214             : /* KNI handling periodicity in US */
     215             : #define VR_DPDK_SLEEP_KNI_US        500
     216             : /* Sleep time in US for service lcore */
     217             : #define VR_DPDK_SLEEP_SERVICE_US    100
     218             : /* Invalid port ID */
     219             : #define VR_DPDK_INVALID_PORT_ID     0xFF
     220             : /* L3MH supports 3 bond interfaces */
     221             : #define VR_DPDK_BOND_PORT_IDS     3
     222             : /* Invalid queue ID */
     223             : #define VR_DPDK_INVALID_QUEUE_ID    0xFFFF
     224             : /* Socket connection retry timeout in seconds (use power of 2) */
     225             : #define VR_DPDK_RETRY_CONNECT_SECS  64
     226             : /* Maximum number of KNI devices (vhost0 + monitoring) */
     227             : #define VR_DPDK_MAX_KNI_INTERFACES  16
     228             : /* Maximum number of TAP devices (vhost0 + monitoring) */
     229             : #define VR_DPDK_MAX_TAP_INTERFACES  16
     230             : /* String buffer size (for logs and EAL arguments) */
     231             : #define VR_DPDK_STR_BUF_SZ          512
     232             : /* Log timestamp format */
     233             : #define VR_DPDK_TIMESTAMP           "%F %T"
     234             : /* Maximum number of fragments allowed after IP fragmentation. Set to 7 to
     235             :  * allow for standard jumbo frame size (9000 / 1500 = 6) + 1 additional segment
     236             :  * for outer headers. */
     237             : #define VR_DPDK_FRAG_MAX_IP_FRAGS   7
     238             : /* Set to 256 just to ensure we have enough buffers in case mss is set
     239             :  * to 256, if the packet size is 64K.
     240             :  */
     241             : #define VR_DPDK_FRAG_MAX_IP_SEGS    256
     242             : #define VR_DPDK_VLAN_FWD_DEF_NAME   "vfw0"
     243             : /*
     244             :  * Use IO lcores:
     245             :  *   true  - IO lcores distribute packet among forwarding lcores
     246             :  *   false - forwarding lcores distribute among other forwarding lcores
     247             :  */
     248             : #define VR_DPDK_USE_IO_LCORES       false
     249             : /*
     250             :  * Whether IO lcore share CPUs with forwarding lcores
     251             :  *   true  - each IO lcore has an affinity mask of all the forwarding
     252             :  *           lcores it distributes packets to
     253             :  *           Example: if core mask is 0xf and FWD_LCORES_PER_IO is 2,
     254             :  *             there are will be 4 forwarding lcores: 7@0,8@1,9@2,10@3
     255             :  *             and 2 shared IO lcores: 3@(0,1),4@(2,3)
     256             :  *   false - IO lcore has a dedicated CPU core
     257             :  *           Example: if core mask is 0x3f and FWD_LCORES_PER_IO is 2,
     258             :  *             there are will be 4 forwarding lcores: 7@1,8@2,9@4,10@5
     259             :  *             and 2 dedicated IO lcores: 3@0,4@3
     260             :  */
     261             : #define VR_DPDK_SHARED_IO_LCORES    false
     262             : /*
     263             :  * Create IO lcore for the specified number of forwarding lcores.
     264             :  * The maximum number of IO lcores is limited by IO lcore IDs below.
     265             :  */
     266             : #define VR_DPDK_FWD_LCORES_PER_IO   3
     267             : 
     268             : /*
     269             :  * Number of open fds needed for vrouter (other than one uvhost fd per
     270             :  * interface)
     271             :  */
     272             : #define VR_DPDK_NUM_FDS    512
     273             : 
     274             : /* Maximum number of HOLD entries in flow table */
     275             : #define VR_DPDK_MAX_FLOW_TABLE_HOLD_COUNT 1000
     276             : /* Maximum number of mbufs in per CPU queues */
     277             : #define VR_DPDK_MAX_FRAGMENT_ELEMENTS     1024ULL
     278             : /*
     279             :  * SR-IOV virtual function PMD name suffix.
     280             :  * Note: only rte_ixgbevf_pmd was tested.
     281             :  */
     282             : #if (RTE_VERSION == RTE_VERSION_NUM(2, 1, 0, 0))
     283             : #define VR_DPDK_VF_PMD_SFX "vf_pmd"
     284             : #define RTE_LOG_DP RTE_LOG
     285             : #else
     286             : #define VR_DPDK_VF_PMD_SFX "_vf"
     287             : #endif
     288             : 
     289             : #define VR_DPDK_MGMTPATH 0
     290             : #define VR_DPDK_DATAPATH 1
     291             : 
     292             : /**
     293             :  * Macro to iterate over all enabled and ownerless dpdk ethdev ports.
     294             :  */
     295             : #if (RTE_VERSION >= RTE_VERSION_NUM(17, 11, 0, 0))
     296             :     #define VR_DPDK_RTE_ETH_FOREACH_DEV(p) \
     297             :         RTE_ETH_FOREACH_DEV(p)
     298             : #else
     299             :     #define VR_DPDK_RTE_ETH_FOREACH_DEV(p) \
     300             :         for (p = 0; p < rte_eth_dev_count(); p++)
     301             : #endif
     302             : 
     303             : /* VHOST Default MTU size*/
     304             : #define VR_DPDK_VHOST_DEFAULT_MTU_SIZE 1500
     305             : 
     306             : /* vr_info - DPDK platform dependent Macro functions
     307             :  * For vr_info, callback functions are registered in vr_info.h,
     308             :  * those callbacks will be expanded below for function declaration and
     309             :  * mapping those functions in vr_dpdk_host.c */
     310             : 
     311             : /* Map only DPDK specific callback functions */
     312             : #undef VR_INFO_HOST_MAP_DPDK
     313             : #define VR_INFO_HOST_MAP_DPDK(MSG, CB) \
     314             :     .hos_vr_##CB = dpdk_##CB,
     315             : 
     316             : #define VR_INFO_HOST_MAP(MSG, CB, PLTFRM) \
     317             :     VR_INFO_HOST_MAP_##PLTFRM(MSG, CB)
     318             : 
     319             : #define FOREACH_VR_INFO_MAP() \
     320             :     VR_INFO_REG(VR_INFO_HOST_MAP)
     321             : 
     322             : #define VR_INFO_DECLARATION(MSG, CB, PLTFRM) \
     323             :     int dpdk_##CB(VR_INFO_ARGS);
     324             : 
     325             : #define FOREACH_VR_INFO_DECLARATION() \
     326             :     VR_INFO_REG(VR_INFO_DECLARATION)
     327             : 
     328             : #define VR_DPDK_DDP_NOT_SUPPORTED -1000
     329             : #define VR_DPDK_DDP_FAILED        -1001
     330             : 
     331             : /*
     332             :  * DPDK LCore IDs
     333             :  */
     334             : enum {
     335             :     VR_DPDK_TAPDEV_LCORE_ID = 0,
     336             :     VR_DPDK_TIMER_LCORE_ID,
     337             :     VR_DPDK_UVHOST_LCORE_ID,
     338             :     /*
     339             :      * The actual number of IO lcores depends on the number of
     340             :      * forwarding lcores.
     341             :      */
     342             :     VR_DPDK_IO_LCORE_ID,
     343             :     VR_DPDK_IO_LCORE_ID2,
     344             :     VR_DPDK_IO_LCORE_ID3,
     345             :     VR_DPDK_IO_LCORE_ID4,
     346             :     VR_DPDK_LAST_IO_LCORE_ID,
     347             :     /* [PACKET_ID..FWD_ID) lcores have TX queues, but no RX queues */
     348             :     VR_DPDK_PACKET_LCORE_ID,
     349             :     VR_DPDK_NETLINK_LCORE_ID,
     350             :     /* The actual number of forwarding lcores depends on affinity mask. */
     351             :     VR_DPDK_FWD_LCORE_ID,
     352             : };
     353             : 
     354             : /* Fabric(Master) & Slave Interface Type */
     355             : enum {
     356             :     VR_DPDK_BOND_MASTER = 1,
     357             :     VR_DPDK_BOND_SLAVE,
     358             : };
     359             : 
     360             : struct vr_dpdk_bond_member_info {
     361             :     char intf_name[VR_INTERFACE_NAME_LEN];
     362             :     char intf_drv_name[VR_INTERFACE_NAME_LEN];
     363             :     bool status;
     364             : };
     365             : 
     366             : /* structure used to store the list of availbale port_ids
     367             :    for net_bonding. For L3MH we will have more then 1 bond interface.
     368             :  */
     369             : struct vr_dpdk_bond_port_list {
     370             :     uint8_t intf_list[VR_DPDK_BOND_PORT_IDS];
     371             :     uint8_t intf_count;
     372             : };
     373             : 
     374             : /* Maximum number of IO lcores */
     375             : #define VR_DPDK_MAX_IO_LORES (VR_DPDK_LAST_IO_LCORE_ID - VR_DPDK_IO_LCORE_ID + 1)
     376             : 
     377             : /* needs to have a place holder for RX flags, to allow usuage of dpdk from upstream */
     378             : #ifndef PKT_RX_GSO_TCP4
     379             : #define PKT_RX_GSO_TCP4      (1ULL << 23)  /**< RX packet with TCPv4 segment offload */
     380             : #endif /* PKT_RX_GSO_TCP4 */
     381             : #ifndef PKT_RX_GSO_TCP6
     382             : #define PKT_RX_GSO_TCP6      (1ULL << 24)  /**< RX packet with TCPv6 segment offload */
     383             : #endif /* PKT_RX_GSO_TCP6 */
     384             : 
     385             : /*
     386             :  * VRouter/DPDK Data Structures
     387             :  * ============================
     388             :  *
     389             :  * Changes since the initial commit:
     390             :  *   lcore_ctx -> vr_dpdk_lcore
     391             :  *   vif_port -> vr_dpdk_queue
     392             :  *
     393             :  * TODO: update the description
     394             :  */
     395             : 
     396             : struct vr_dpdk_rcu_cb_data {
     397             :     struct rcu_head rcd_rcu;
     398             :     vr_defer_cb rcd_user_cb;
     399             :     struct vrouter *rcd_router;
     400             :     unsigned char rcd_user_data[];
     401             : };
     402             : 
     403             : /* Init queue operation */
     404             : typedef struct vr_dpdk_queue *
     405             :     (*vr_dpdk_queue_init_op)(unsigned lcore_id, struct vr_interface *vif,
     406             :         unsigned queue_or_lcore_id);
     407             : /* Release queue operation */
     408             : typedef void
     409             :     (*vr_dpdk_queue_release_op)(unsigned lcore_id, unsigned queue_index,
     410             :             struct vr_interface *vif);
     411             : 
     412             : struct vr_dpdk_queue {
     413             :     SLIST_ENTRY(vr_dpdk_queue) q_next;
     414             :     union {
     415             :         /* DPDK TX queue operators */
     416             :         struct rte_port_out_ops txq_ops;
     417             :         /* DPDK RX queue operators */
     418             :         struct rte_port_in_ops rxq_ops;
     419             :     };
     420             :     /* Queue handler */
     421             :     void *q_queue_h;
     422             :     /* Enabled/disabled (whether polled by lcores) */
     423             :     bool enabled;
     424             :     /* Pointer to vRouter interface */
     425             :     struct vr_interface *q_vif;
     426             :     /* Incase of multiqueue, store vring queue_id */
     427             :     uint16_t vring_queue_id;
     428             : };
     429             : 
     430             : /* We store the queue params in the separate structure to increase CPU
     431             :  * cache hit rate
     432             :  */
     433             : struct vr_dpdk_queue_params {
     434             :     /* Pointer to release function */
     435             :     vr_dpdk_queue_release_op qp_release_op;
     436             :     /* Extra queue params */
     437             :     union {
     438             :         struct {
     439             :             struct rte_ring *ring_p;
     440             :             unsigned host_lcore_id;
     441             :         } qp_ring;
     442             :         struct {
     443             :             uint8_t port_id;
     444             :             uint16_t queue_id;
     445             :         } qp_ethdev;
     446             :     };
     447             : };
     448             : 
     449             : struct vr_dpdk_ring_to_push {
     450             :     /* Ring pointer */
     451             :     struct rte_ring *rtp_tx_ring;
     452             :     /* TX queue pointer */
     453             :     struct vr_dpdk_queue *rtp_tx_queue;
     454             : };
     455             : 
     456             : SLIST_HEAD(vr_dpdk_q_slist, vr_dpdk_queue);
     457             : 
     458             : /* Lcore commands */
     459             : enum vr_dpdk_lcore_cmd {
     460             :     /* No command */
     461             :     VR_DPDK_LCORE_NO_CMD = 0,
     462             :     /* Command arguments are being published */
     463             :     VR_DPDK_LCORE_IN_PROGRESS_CMD,
     464             :     /* Stop and exit the lcore loop */
     465             :     VR_DPDK_LCORE_STOP_CMD,
     466             :     /* Remove RX queue */
     467             :     VR_DPDK_LCORE_RX_RM_CMD,
     468             :     /* Remove TX queue */
     469             :     VR_DPDK_LCORE_TX_RM_CMD,
     470             :     /* Call RCU callback */
     471             :     VR_DPDK_LCORE_RCU_CMD,
     472             :     /* TX queue disable/enable command */
     473             :     VR_DPDK_LCORE_TX_QUEUE_SET_CMD,
     474             :     /* RX queue disable/enable command */
     475             :     VR_DPDK_LCORE_RX_QUEUE_SET_CMD,
     476             : };
     477             : 
     478             : struct gro_ctrl {
     479             :     int     gro_queued;
     480             :     int     gro_flushed;
     481             :     int     gro_bad_csum;
     482             :     int     gro_cnt;
     483             :     int     gro_flows;
     484             :     int     gro_flush_inactive_flows;
     485             : 
     486             :     struct rte_hash *gro_tbl_v4_handle;
     487             :     struct rte_hash *gro_tbl_v6_handle;
     488             : };
     489             : 
     490             : struct vr_dpdk_lcore_rx_queue_remove_arg {
     491             :     unsigned int vif_id;
     492             :     bool clear_f_rx;
     493             :     bool free_arg;
     494             : };
     495             : 
     496             : struct vr_dpdk_lcore {
     497             :     /**********************************************************************/
     498             :     /* Frequently used fields */
     499             :     /* RX queues head */
     500             :     struct vr_dpdk_q_slist lcore_rx_head;
     501             :     /* TX queues head */
     502             :     struct vr_dpdk_q_slist lcore_tx_head;
     503             :     /* Forwarding lcore: number of rings to push for the lcore */
     504             :     volatile uint16_t lcore_nb_rings_to_push;
     505             :     /* Forwarding lcore: number of bond queues to TX */
     506             :     volatile uint16_t lcore_nb_bonds_to_tx;
     507             :     /* Number of hardware RX queues assigned to the lcore (for the scheduler) */
     508             :     uint16_t lcore_nb_rx_queues;
     509             :     /* Lcore command */
     510             :     volatile uint16_t lcore_cmd;
     511             :     /* Lcore command arguments */
     512             :     volatile uint64_t lcore_cmd_arg;
     513             :     /* RX ring with packets from other lcores (i.e. for MPLSoGRE). */
     514             :     struct rte_ring *lcore_rx_ring;
     515             :     /* RX ring with packets from IO lcore. */
     516             :     struct rte_ring *lcore_io_rx_ring;
     517             :     /* Number of forwarding loops */
     518             :     u_int64_t lcore_fwd_loops;
     519             :     /* Flag controlling the assembler work */
     520             :     bool do_fragment_assembly;
     521             :     /* GRO ctrl structure */
     522             :     struct gro_ctrl gro;
     523             : 
     524             :     /**********************************************************************/
     525             :     /* Big and less frequently used fields */
     526             :     /* Number of lcores to distribute packets to */
     527             :     uint16_t lcore_nb_dst_lcores;
     528             :     /* List of forwarding lcore indexes based on VR_DPDK_FWD_LCORE_ID */
     529             :     uint16_t lcore_dst_lcore_idxs[VR_MAX_CPUS_DPDK];
     530             :     /* Table of RX queues */
     531             :     struct vr_dpdk_queue lcore_rx_queues[VR_MAX_INTERFACES];
     532             :     /* Table of TX queues */
     533             :     struct vr_dpdk_queue *lcore_tx_queues[VR_MAX_INTERFACES] __rte_cache_aligned;
     534             :     /* List of rings to push */
     535             :     struct vr_dpdk_ring_to_push lcore_rings_to_push[VR_DPDK_MAX_RINGS] __rte_cache_aligned;
     536             :     /* List of bond queue params to TX LACP packets periodically */
     537             :     struct vr_dpdk_queue_params *lcore_bonds_to_tx[VR_DPDK_MAX_BONDS] __rte_cache_aligned;
     538             :     /* Table of RX queue params */
     539             :     struct vr_dpdk_queue_params lcore_rx_queue_params[VR_MAX_INTERFACES] __rte_cache_aligned;
     540             :     /* Table of TX queue params */
     541             :     struct vr_dpdk_queue_params *lcore_tx_queue_params[VR_MAX_INTERFACES] __rte_cache_aligned;
     542             :     /*
     543             :      * number of queues/lcore - basically one hardware queue + rings
     544             :      * to other cores that hosts each hardware queue
     545             :      *
     546             :      * If hardware queueing is supported, num_tx_queues_per_lcore will
     547             :      * be equal to the number of queues that the agent wants to use.
     548             :      * The number of queues that the agent wants to use is set in the
     549             :      * vr_interface structure (vif_num_hw_queues). agent will read its
     550             :      * configuration file and tell vRouter the queue numbers it wants
     551             :      * to use (and hence the number of queues) and set this information
     552             :      * in vif_hw_queues
     553             :      */
     554             :     uint16_t num_tx_queues_per_lcore[VR_MAX_INTERFACES];
     555             :     /* for each vif, the first hardware queue that is tied to this lcore */
     556             :     int16_t lcore_hw_queue[VR_MAX_INTERFACES];
     557             :     /*
     558             :      * given a hardware queue, the index to the array of vr_dpdk_queue.
     559             :      * Enables us to get the queue faster
     560             :      */
     561             :     int16_t *lcore_hw_queue_to_dpdk_index[VR_MAX_INTERFACES];
     562             :     void (*fragment_assembly_func)(void *arg);
     563             :     void *fragment_assembly_arg;
     564             : };
     565             : 
     566             : /* Hardware RX queue state */
     567             : enum vr_dpdk_queue_state {
     568             :     /* No queue available */
     569             :     VR_DPDK_QUEUE_NONE,
     570             :     /* The queue is ready to use for RSS or filtering */
     571             :     VR_DPDK_QUEUE_READY_STATE,
     572             :     /* The queue is being used for RSS */
     573             :     VR_DPDK_QUEUE_RSS_STATE,
     574             :     /* The queue is being used for filtering */
     575             :     VR_DPDK_QUEUE_FILTERING_STATE
     576             : };
     577             : 
     578             : struct vif_queue_dpdk_data {
     579             :     int16_t vqdd_queue_to_lcore[VR_DPDK_MAX_NB_TX_QUEUES];
     580             : };
     581             : 
     582             : /* Ethdev configuration */
     583             : struct vr_dpdk_ethdev {
     584             :     /* Pointer to ethdev or NULL if the device is not used */
     585             :     struct rte_eth_dev *ethdev_ptr;
     586             :     /* Number of HW RX queues (limited by NIC hardware) */
     587             :     uint16_t ethdev_nb_rx_queues;
     588             :     /* Number of HW TX queues (limited by the nb of lcores) */
     589             :     uint16_t ethdev_nb_tx_queues;
     590             :     /* Number of HW RX queues used for RSS (limited by the nb of lcores) */
     591             :     uint16_t ethdev_nb_rss_queues;
     592             :     /* Actual size of ethdev RETA */
     593             :     uint16_t ethdev_reta_size;
     594             :     /* DPDK port ID */
     595             : #if (RTE_VERSION >= RTE_VERSION_NUM(17, 11, 0, 0))
     596             :     uint16_t ethdev_port_id;
     597             : #else
     598             :     uint8_t ethdev_port_id;
     599             : #endif
     600             :     /* The device is a bond if the number of slaves is > 0 */
     601             :     int8_t ethdev_nb_slaves;
     602             :     /* List of slaves port IDs */
     603             : #if (RTE_VERSION >= RTE_VERSION_NUM(17, 11, 0, 0))
     604             :     uint16_t ethdev_slaves[VR_DPDK_BOND_MAX_SLAVES];
     605             : #else
     606             :     uint8_t ethdev_slaves[VR_DPDK_BOND_MAX_SLAVES];
     607             : #endif
     608             :     /* Hardware RX queue states */
     609             :     uint8_t ethdev_queue_states[VR_DPDK_MAX_NB_RX_QUEUES];
     610             :     /* Pointers to memory pools */
     611             :     struct rte_mempool *ethdev_mempools[VR_DPDK_MAX_NB_RX_QUEUES];
     612             :     /* Vif interface Id */
     613             :     uint8_t ethdev_vif_idx;
     614             :     /* Port lock. */
     615             :     rte_spinlock_t ethdev_lock;
     616             : };
     617             : 
     618             : /* Tapdev configuration. */
     619             : struct vr_dpdk_tapdev {
     620             :     /* Tapdev file descriptor. */
     621             :     volatile int tapdev_fd;
     622             :     /* Tapdev file descriptor for vhost0. */
     623             :     int tapdev_vhost_fd;
     624             :     /* RX ring. */
     625             :     struct rte_ring *tapdev_rx_ring;
     626             :     /* TX rings (single-producer single-consumer) */
     627             :     struct rte_ring *tapdev_tx_rings[RTE_MAX_LCORE];
     628             :     /* Pointer to vif. */
     629             :     struct vr_interface *tapdev_vif;
     630             :     /* Name of the corresponding device on kernel. */
     631             :     char tapdev_name[VR_INTERFACE_NAME_LEN];
     632             : };
     633             : 
     634             : struct vr_dpdk_global {
     635             :     /**********************************************************************/
     636             :     /* Frequently used fields */
     637             :     /* Pointer to main (RSS) memory pool */
     638             :     struct rte_mempool *rss_mempool;
     639             :     /* Packet socket ring */
     640             :     struct rte_ring *packet_ring;
     641             :     /* Global stop flag */
     642             :     rte_atomic16_t stop_flag;
     643             :     /* VLAN tag */
     644             :     uint16_t vlan_tag;
     645             :     /* We are use it in unittest application (vtest) for vlan
     646             :      * adding workaround for virtual interfaces. */
     647             :     uint16_t vtest_vlan;
     648             :     /* Number of forwarding lcores */
     649             :     uint16_t nb_fwd_lcores;
     650             :     /* Number of IO lcores */
     651             :     uint16_t nb_io_lcores;
     652             :     /* Packet lcore event socket
     653             :      * TODO: refactor to use event FD
     654             :      */
     655             :     void *packet_event_sock;
     656             :     /* NetLink lcore event socket */
     657             :     void *netlink_event_sock;
     658             :     /* Event FD to wake up UVHost */
     659             :     int uvhost_event_fd;
     660             : 
     661             :     /* Table of pointers to forwarding lcore
     662             :      * Must be at the end of the cache line 1 */
     663             :     struct vr_dpdk_lcore *lcores[VR_MAX_CPUS_DPDK];
     664             : 
     665             :     /**********************************************************************/
     666             :     /* Big and less frequently used fields */
     667             :     /* Number of free memory pools */
     668             :     uint16_t nb_free_mempools;
     669             :     /* NetLink socket handler */
     670             :     void *netlink_sock;
     671             :     void *flow_table;
     672             :     void *bridge_table;
     673             :     /* Packet socket */
     674             :     void *packet_transport;
     675             :     /* Interface configuration mutex
     676             :      * ATM we use it just to synchronize access between the NetLink interface
     677             :      * and kernel KNI events. The datapath is not affected. */
     678             :     pthread_mutex_t if_lock;
     679             :     /* Pointer to IP fragmentation memory pool (direct) */
     680             :     struct rte_mempool *frag_direct_mempool;
     681             :     /* Pointer to IP fragmentation memory pool (indirect) */
     682             :     struct rte_mempool *frag_indirect_mempool;
     683             :     /* List of free memory pools */
     684             :     struct rte_mempool *free_mempools[VR_DPDK_MAX_VM_MEMPOOLS] __rte_cache_aligned;
     685             :     /* List of KNI interfaces to handle KNI requests */
     686             :     struct rte_kni *knis[VR_DPDK_MAX_KNI_INTERFACES] __rte_cache_aligned;
     687             :     /* Table of monitoring redirections (for vifdump) */
     688             :     uint16_t monitorings[VR_MAX_INTERFACES] __rte_cache_aligned;
     689             :     /* Table of ethdevs */
     690             :     struct vr_dpdk_ethdev ethdevs[RTE_MAX_ETHPORTS] __rte_cache_aligned;
     691             :     /* Table of tapdevs. */
     692             :     struct vr_dpdk_tapdev tapdevs[VR_DPDK_MAX_TAP_INTERFACES] __rte_cache_aligned;
     693             :     /* netlink socket to listen to link up/down and mtu change notifications */
     694             :     volatile int tap_nl_fd;
     695             :     /* VLAN forwarding interface name */
     696             :     char vlan_name[VR_INTERFACE_NAME_LEN];
     697             :     /* VLAN forwarding interface ring */
     698             :     struct rte_ring *vlan_ring;
     699             :     /* VLAN forwarding device pointer. */
     700             :     void *vlan_dev;
     701             :     /* VLAN forwarding interface vif. */
     702             :     struct vr_interface *vlan_vif;
     703             :     /* Dedicated IO lcore for SR-IOV VF. */
     704             :     unsigned vf_lcore_id;
     705             :     /*
     706             :      * KNI global state flag:
     707             :      *  0 - initial state
     708             :      *  1 - KNI is enabled
     709             :      * -1 - KNI is not available, so TAP interfaces are used instead
     710             :      */
     711             :     int kni_state;
     712             : };
     713             : 
     714             : extern struct vr_dpdk_global vr_dpdk;
     715             : extern struct rte_eth_conf ethdev_conf;
     716             : 
     717             : /*
     718             :  * rte_mbuf <=> vr_packet conversion
     719             :  *
     720             :  * The vr_packet structure is right after the rte_mbuf:
     721             :  *     struct rte_mbuf + struct vr_packet + headroom + data + tailroom
     722             :  *
     723             :  * rte_mbuf: *buf_addr(buf_len) + headroom + data_off(data_len) + tailroom
     724             :  *
     725             :  * rte_mbuf->buf_addr = rte_mbuf + sizeof(rte_mbuf) + sizeof(vr_packet)
     726             :  * rte_mbuf->buf_len = elt_size - sizeof(rte_mbuf) - sizeof(vr_packet)
     727             :  * rte_mbuf->data_off = RTE_PKTMBUF_HEADROOM
     728             :  *
     729             :  *
     730             :  * vr_packet: *vp_head + headroom + vp_data(vp_len) + vp_tail + tailroom
     731             :  *                + vp_end
     732             :  *
     733             :  * vr_packet->vp_head = rte_mbuf->buf_addr (set in mbuf constructor)
     734             :  * vr_packet->vp_data = rte_mbuf->data_off
     735             :  * vr_packet->vp_len  = rte_mbuf->data_len
     736             :  * vr_packet->vp_tail = vr_packet->vp_data + vr_packet->vp_len
     737             :  * vr_packet->vp_end  = rte_mbuf->buf_len (set in mbuf constructor)
     738             :  */
     739             : static inline struct rte_mbuf *
     740        1390 : vr_dpdk_pkt_to_mbuf(struct vr_packet *pkt)
     741             : {
     742        1390 :     return (struct rte_mbuf *)((uintptr_t)pkt - sizeof(struct rte_mbuf));
     743             : }
     744             : static inline struct vr_packet *
     745      868534 : vr_dpdk_mbuf_to_pkt(struct rte_mbuf *mbuf)
     746             : {
     747      868534 :     return (struct vr_packet *)((uintptr_t)mbuf + sizeof(struct rte_mbuf));
     748             : }
     749             : 
     750             : /*
     751             :  * vr_dpdk_mbuf_reset - if the mbuf changes, possibley due to
     752             :  * pskb_may_pull, reset fields of the pkt structure that point at
     753             :  * the mbuf fields.
     754             :  * Note: we do not reset pkt->data here
     755             :  */
     756             : static inline void
     757           0 : vr_dpdk_mbuf_reset(struct vr_packet *pkt)
     758             : {
     759           0 :     struct rte_mbuf *mbuf = vr_dpdk_pkt_to_mbuf(pkt);
     760             : 
     761           0 :     pkt->vp_head = mbuf->buf_addr;
     762           0 :     pkt->vp_tail = rte_pktmbuf_headroom(mbuf) + mbuf->data_len;
     763           0 :     pkt->vp_end = mbuf->buf_len;
     764           0 :     pkt->vp_len = pkt->vp_tail - pkt->vp_data;
     765             : 
     766           0 :     return;
     767             : }
     768             : 
     769             : /*
     770             :  * dpdk_vrouter.c
     771             :  */
     772             : /* A packet mbuf pool constructor with vr_packet support */
     773             : void vr_dpdk_pktmbuf_pool_init(struct rte_mempool *mp, void *opaque_arg);
     774             : /* The packet mbuf constructor with vr_packet support */
     775             : void vr_dpdk_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg, void *_m, unsigned i);
     776             : /* Check if the stop flag is set */
     777             : int vr_dpdk_is_stop_flag_set(void);
     778             : /* Called by user space vhost server at exit */
     779             : void vr_dpdk_exit_trigger(void);
     780             : 
     781             : /*
     782             :  * vr_dpdk_ethdev.c
     783             :  */
     784             : /* Init eth RX queue */
     785             : struct vr_dpdk_queue *
     786             : vr_dpdk_ethdev_rx_queue_init(unsigned lcore_id, struct vr_interface *vif,
     787             :     unsigned rx_queue_id);
     788             : /* Init eth TX queue */
     789             : struct vr_dpdk_queue *
     790             : vr_dpdk_ethdev_tx_queue_init(unsigned lcore_id, struct vr_interface *vif,
     791             :     unsigned tx_queue_id);
     792             : /* Init ethernet device */
     793             : int vr_dpdk_ethdev_init(struct vr_dpdk_ethdev *, struct rte_eth_conf *,
     794             :     struct rte_eth_txconf *, struct rte_eth_rxconf *);
     795             : /* Release ethernet device */
     796             : int vr_dpdk_ethdev_release(struct vr_dpdk_ethdev *);
     797             : /* Get free queue ID */
     798             : uint16_t vr_dpdk_ethdev_ready_queue_id_get(struct vr_interface *vif);
     799             : 
     800             : #if VR_DPDK_USE_HW_FILTERING
     801             : /* Add hardware filter */
     802             : int vr_dpdk_ethdev_filter_add(struct vr_interface *vif, uint16_t queue_id,
     803             :     unsigned dst_ip, unsigned mpls_label);
     804             : /* Init hardware filtering */
     805             : int vr_dpdk_ethdev_filtering_init(struct vr_interface *vif, struct vr_dpdk_ethdev *ethdev);
     806             : #endif
     807             : 
     808             : /* Init RSS */
     809             : int vr_dpdk_ethdev_rss_init(struct vr_dpdk_ethdev *ethdev);
     810             : /*
     811             :  * vr_dpdk_ethdev_rx_emulate - emulate smart NIC RX:
     812             :  *  - strip VLAN tags for packets received from fabric interface
     813             :  *  - calculate RSS hash if it is not present
     814             :  *  - recalculate RSS hash for MPLSoGRE packets
     815             :  *
     816             :  * Returns 0 on no hash changes, otherwise a bitmask of mbufs to distribute.
     817             :  */
     818             : uint64_t vr_dpdk_ethdev_rx_emulate(struct vr_interface *vif,
     819             :     struct rte_mbuf *pkts[VR_DPDK_RX_BURST_SZ], uint32_t *nb_pkts);
     820             : /* Check if port_id is a bond slave. */
     821             : bool vr_dpdk_ethdev_bond_port_match(uint8_t port_id, struct vr_dpdk_ethdev *ethdev);
     822             : /* Send bond interface state to Agent. */
     823             : void vr_dpdk_nl_send_bond_intf_state(struct vr_dpdk_bond_member_info *info,
     824             :     unsigned type, uint8_t vif_idx);
     825             : 
     826             : int vr_dpdk_table_mem_init(unsigned int, unsigned int, unsigned long,
     827             :         unsigned int, unsigned long);
     828             : int vr_dpdk_flow_init(void);
     829             : int vr_dpdk_bridge_init(void);
     830             : 
     831             : extern uint32_t vr_dpdk_master_port_id;
     832             : 
     833             : /*
     834             :  * vr_dpdk_ddp.c
     835             :  */
     836             : enum {
     837             :     VR_DPDK_DDP_UNDEFINED = 0,
     838             :     VR_DPDK_DDP_ADD,
     839             :     VR_DPDK_DDP_DELETE
     840             : };
     841             : bool vr_dpdk_get_ddp(void);
     842             : void vr_dpdk_set_ddp(void);
     843             : void vr_dpdk_reset_ddp(void);
     844             : int vr_dpdk_process_ddp_package(unsigned);
     845             : 
     846             : /*
     847             :  * vr_dpdk_host.c
     848             :  */
     849             : int vr_dpdk_host_init(void);
     850             : void vr_dpdk_host_exit(void);
     851             : /* Convert internal packet fields */
     852             : struct vr_packet * vr_dpdk_packet_get(struct rte_mbuf *m, struct vr_interface *vif);
     853             : void vr_dpdk_pfree(struct rte_mbuf *mbuf, struct vr_interface *vif, unsigned short reason);
     854             : /* Retry socket connection */
     855             : int vr_dpdk_retry_connect(int sockfd, const struct sockaddr *addr,
     856             :                             socklen_t alen);
     857             : /* Generates unique log message */
     858             : int vr_dpdk_ulog(uint32_t level, uint32_t logtype, uint32_t *last_hash,
     859             :                     const char *format, ...);
     860             : #if (RTE_LOG_LEVEL == RTE_LOG_DEBUG)
     861             : #define DPDK_DEBUG_VAR(v) v
     862             : #define DPDK_UDEBUG(t, h, ...)                          \
     863             :     (void)(((RTE_LOG_DEBUG <= RTE_LOG_LEVEL) &&         \
     864             :         (RTE_LOG_DEBUG <= rte_logs.level) &&            \
     865             :         (RTE_LOGTYPE_ ## t & rte_logs.type)) ?          \
     866             :     vr_dpdk_ulog(RTE_LOG_DEBUG,                         \
     867             :         RTE_LOGTYPE_ ## t, h, # t ": " __VA_ARGS__) : 0)
     868             : #else
     869             : #define DPDK_DEBUG_VAR(v)
     870             : #define DPDK_UDEBUG(t, h, ...)
     871             : #endif
     872             : /* Helper to adjust TCP MSS */
     873             : void dpdk_adjust_tcp_mss(struct tcphdr *tcph, unsigned short overlay_len,
     874             :                             unsigned char iph_len);
     875             : /* Creates a copy of the given packet mbuf */
     876             : struct rte_mbuf *
     877             : vr_dpdk_pktmbuf_copy(struct rte_mbuf *md, struct rte_mempool *mp);
     878             : struct rte_mbuf *
     879             : vr_dpdk_pktmbuf_copy_mon(struct rte_mbuf *md, struct rte_mempool *mp);
     880             : 
     881             : /*
     882             :  * vr_dpdk_interface.c
     883             :  */
     884             : /* Lock interface operations */
     885        1035 : static inline int vr_dpdk_if_lock()
     886        1035 : { return pthread_mutex_lock(&vr_dpdk.if_lock); }
     887             : /* Unlock interface operations */
     888        1035 : static inline int vr_dpdk_if_unlock()
     889        1035 : { return pthread_mutex_unlock(&vr_dpdk.if_lock); }
     890             : static inline uint16_t
     891         126 : dpdk_get_ether_header_len(const void *data)
     892             : {
     893         126 :     struct rte_ether_hdr *eth = (struct rte_ether_hdr *)data;
     894             : 
     895         126 :     if (eth->ether_type == rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN))
     896           0 :         return sizeof(struct rte_ether_hdr) + sizeof(struct rte_vlan_hdr);
     897             :     else
     898         126 :         return sizeof(struct rte_ether_hdr);
     899             : }
     900             : 
     901             : 
     902             : /*
     903             :  * vr_dpdk_tapdev.c
     904             :  */
     905             : /* Init TAP device. */
     906             : int vr_dpdk_tapdev_init(struct vr_interface *vif);
     907             : /* Release TAP device. */
     908             : int vr_dpdk_tapdev_release(struct vr_interface *vif);
     909             : /* Init TAP RX queue. */
     910             : struct vr_dpdk_queue *
     911             : vr_dpdk_tapdev_rx_queue_init(unsigned lcore_id, struct vr_interface *vif,
     912             :     unsigned queue_id);
     913             : /* Init TAP TX queue. */
     914             : struct vr_dpdk_queue *
     915             : vr_dpdk_tapdev_tx_queue_init(unsigned lcore_id, struct vr_interface *vif,
     916             :     unsigned queue_id);
     917             : /* RX/TX to/from all the TAP devices. */
     918             : uint64_t vr_dpdk_tapdev_rxtx(void);
     919             : /* RX a burst of packets from the TAP device. */
     920             : unsigned vr_dpdk_tapdev_rx_burst(struct vr_dpdk_tapdev *, struct rte_mbuf **,
     921             :         unsigned num, int datapath);
     922             : /* Dequeue a burst of packets from the TAP device. */
     923             : unsigned vr_dpdk_tapdev_dequeue_burst(struct vr_dpdk_tapdev *, struct rte_mbuf **,
     924             :         unsigned num);
     925             : /* TX a burst of packets to the TAP device. */
     926             : unsigned vr_dpdk_tapdev_tx_burst(struct vr_dpdk_tapdev *, struct rte_mbuf **,
     927             :         unsigned num, int datapath);
     928             : /* Enqueue a burst of packets to the TAP device. */
     929             : unsigned vr_dpdk_tapdev_enqueue_burst(struct vr_dpdk_tapdev *, struct rte_mbuf **,
     930             :         unsigned num);
     931             : void vr_dpdk_tapdev_handle_notifications(void);
     932             : 
     933             : /*
     934             :  * vr_dpdk_packet.c
     935             :  */
     936             : void vr_dpdk_packet_wakeup(struct vr_interface *vif);
     937             : int dpdk_packet_socket_init(void);
     938             : void dpdk_packet_socket_close(void);
     939             : int dpdk_packet_io(void);
     940             : /* RCU callback called on packet lcore */
     941             : void vr_dpdk_packet_rcu_cb(struct rcu_head *rh);
     942             : /* Work callback called on packet lcore */
     943             : void vr_dpdk_packet_work_cb(void (*fn)(void *), void *arg);
     944             : 
     945             : /*
     946             :  * vr_dpdk_lcore.c
     947             :  */
     948             : /* Launch lcore main loop */
     949             : int vr_dpdk_lcore_launch(void *dummy);
     950             : /* Schedule an interface */
     951             : int vr_dpdk_lcore_if_schedule(struct vr_interface *vif, unsigned least_used_id,
     952             :     uint16_t nb_rx_queues, vr_dpdk_queue_init_op rx_queue_init_op,
     953             :     uint16_t nb_tx_queues, vr_dpdk_queue_init_op tx_queue_init_op);
     954             : /* Unschedule an interface */
     955             : void vr_dpdk_lcore_if_unschedule(struct vr_interface *vif);
     956             : /* Schedule an MPLS label queue */
     957             : int vr_dpdk_lcore_mpls_schedule(struct vr_interface *vif, unsigned dst_ip,
     958             :     unsigned mpls_label);
     959             : /* Returns the least used lcore or VR_MAX_CPUS_DPDK */
     960             : unsigned vr_dpdk_lcore_least_used_get(void);
     961             : size_t vr_dpdk_lcore_free_lcore_get(void);
     962             : /* Flush TX queues */
     963             : static inline void
     964    59280213 : vr_dpdk_lcore_flush(struct vr_dpdk_lcore *lcore)
     965             : {
     966             :     struct vr_dpdk_queue *tx_queue;
     967             : 
     968   231973998 :     SLIST_FOREACH(tx_queue, &lcore->lcore_tx_head, q_next) {
     969   172741853 :         tx_queue->txq_ops.f_flush(tx_queue->q_queue_h);
     970             :     }
     971    59232145 : }
     972             : /*
     973             :  * Distribute mbufs among forwarding lcores using hash.rss.
     974             :  * The destination lcores are listed in lcore->lcore_dst_lcores.
     975             :  */
     976             : void
     977             : vr_dpdk_lcore_distribute(struct vr_dpdk_lcore *lcore, const bool io_lcore,
     978             :     struct vr_interface *vif, struct rte_mbuf *pkts[VR_DPDK_RX_BURST_SZ],
     979             :     uint32_t nb_pkts);
     980             : /* Pass mbufs to dp-core. */
     981             : void
     982             : vr_dpdk_lcore_vroute(struct vr_dpdk_lcore *lcore, struct vr_interface *vif,
     983             :     struct rte_mbuf *pkts[VR_DPDK_RX_BURST_SZ], uint32_t nb_pkts);
     984             : /* Handle an IPC command */
     985             : int vr_dpdk_lcore_cmd_handle(struct vr_dpdk_lcore *lcore);
     986             : /* Busy wait for a command to complete on a specific lcore */
     987             : void vr_dpdk_lcore_cmd_wait(unsigned lcore_id);
     988             : /* Post an lcore command to a specific lcore */
     989             : void
     990             : vr_dpdk_lcore_cmd_post(unsigned lcore_id, uint16_t cmd, uint64_t cmd_arg);
     991             : /* Post an lcore command to all the lcores */
     992             : void vr_dpdk_lcore_cmd_post_all(uint16_t cmd, uint64_t cmd_arg);
     993             : /* Schedule an asslembler work on an lcore */
     994             : void vr_dpdk_lcore_schedule_assembler_work(struct vr_dpdk_lcore *lcore,
     995             :         void (*fun)(void *arg), void *arg);
     996             : void dpdk_lcore_exit(unsigned lcore_id);
     997             : /*
     998             :  * vr_dpdk_netlink.c
     999             :  */
    1000             : void vr_dpdk_netlink_wakeup(void);
    1001             : void dpdk_netlink_exit(void);
    1002             : int dpdk_netlink_init(void);
    1003             : int dpdk_netlink_receive(void *usockp, char *nl_buf, unsigned int nl_len);
    1004             : 
    1005             : extern unsigned int vr_dpdk_rx_ring_sz, vr_dpdk_tx_ring_sz;
    1006             : extern unsigned int vr_dpdk_yield_option;
    1007             : 
    1008             : /*
    1009             :  * vr_dpdk_ringdev.c
    1010             :  */
    1011             : /* Allocates a new ring */
    1012             : struct rte_ring *
    1013             : vr_dpdk_ring_allocate(unsigned host_lcore_id, char *ring_name,
    1014             :     unsigned vr_dpdk_tx_ring_sz, unsigned flags);
    1015             : /* Init ring RX queue */
    1016             : struct vr_dpdk_queue *
    1017             : vr_dpdk_ring_rx_queue_init(unsigned lcore_id, struct vr_interface *vif,
    1018             :     unsigned host_lcore_id);
    1019             : /* Init ring TX queue */
    1020             : struct vr_dpdk_queue *
    1021             : vr_dpdk_ring_tx_queue_init(unsigned lcore_id, struct vr_interface *vif,
    1022             :         unsigned int queue_id, unsigned host_lcore_id);
    1023             : void dpdk_ring_to_push_add(unsigned lcore_id, struct rte_ring *tx_ring,
    1024             :     struct vr_dpdk_queue *tx_queue);
    1025             : 
    1026             : void
    1027             : dpdk_ring_to_push_remove(unsigned lcore_id, struct rte_ring *tx_ring);
    1028             : 
    1029             : /*
    1030             :  * vr_dpdk_fragment_assembler.c
    1031             :  */
    1032             : int dpdk_fragment_assembler_init(void);
    1033             : void dpdk_fragment_assembler_exit(void);
    1034             : int dpdk_fragment_assembler_enqueue(struct vrouter *router,
    1035             :         struct vr_packet *pkt, struct vr_forwarding_md *fmd);
    1036             : void dpdk_fragment_sync_assemble(struct vr_fragment_queue_element *vfqe);
    1037             : void dpdk_fragment_assembler_table_scan(void *);
    1038             : void dpdk_gro_free_all_flows(struct vr_dpdk_lcore *lcore);
    1039             : void dpdk_gro_flush_all_inactive(struct vr_dpdk_lcore *lcore);
    1040             : int dpdk_gro_process(struct vr_packet *pkt, struct vr_interface *vif, bool l2_pkt);
    1041             : int dpdk_segment_packet(struct vr_packet *pkt, struct rte_mbuf *mbuf_in,
    1042             :                 struct rte_mbuf **mbuf_out, const unsigned short out_num,
    1043             :                 const unsigned short mss_size, bool do_outer_ip_csum);
    1044             : uint16_t dpdk_ipv4_udptcp_cksum(struct rte_mbuf *m,
    1045             :                        const struct rte_ipv4_hdr *ipv4_hdr,
    1046             :                        uint8_t *l4_hdr);
    1047             : uint16_t dpdk_ipv6_udptcp_cksum(struct rte_mbuf *m,
    1048             :                        const struct rte_ipv6_hdr *ipv6_hdr,
    1049             :                        uint8_t *l4_hdr);
    1050             : int dpdk_check_rx_mrgbuf_disable(void);
    1051             : 
    1052             : /*
    1053             :  * vr_dpdk_cpuflags.c
    1054             :  */
    1055             : void vr_dpdk_init_cpuid(struct vr_cpu_type_t *cpu);
    1056             : 
    1057             : /*
    1058             :  * Get bond interface port id by drv_name
    1059             :  */
    1060             : uint8_t dpdk_find_port_id_by_vif_name(struct vr_interface *);
    1061             : 
    1062             : /*
    1063             :  * Get all bond interface port ids
    1064             :  */
    1065             : bool dpdk_find_bond_port_id_list(struct vr_dpdk_bond_port_list *);
    1066             : 
    1067             : /*
    1068             :  * vr_dpdk_interface.c
    1069             :  */
    1070             : int vr_dpdk_interface_queue_setup(struct vr_interface *vif);
    1071             : void vr_dpdk_interface_queue_free(struct vr_interface *vif);
    1072             : 
    1073             : /*
    1074             :  * Get DPDK info
    1075             :  */
    1076             : /* Below macro would be expanded for declaring the DPDK callback function
    1077             :  * used for vr_info */
    1078             : FOREACH_VR_INFO_DECLARATION()
    1079             : 
    1080             : #endif /*_VR_DPDK_H_ */

Generated by: LCOV version 1.14