1b77f6600SCristian Dumitrescu /* SPDX-License-Identifier: BSD-3-Clause 2b77f6600SCristian Dumitrescu * Copyright(c) 2020 Intel Corporation 3b77f6600SCristian Dumitrescu */ 4b77f6600SCristian Dumitrescu 5b77f6600SCristian Dumitrescu #include <stdlib.h> 6b77f6600SCristian Dumitrescu #include <string.h> 7e2b8dc52SVenkata Suresh Kumar P #include <netinet/in.h> 8e2b8dc52SVenkata Suresh Kumar P #ifdef RTE_EXEC_ENV_LINUX 9e2b8dc52SVenkata Suresh Kumar P #include <linux/if.h> 10e2b8dc52SVenkata Suresh Kumar P #include <linux/if_tun.h> 11e2b8dc52SVenkata Suresh Kumar P #endif 12e2b8dc52SVenkata Suresh Kumar P #include <sys/ioctl.h> 13e2b8dc52SVenkata Suresh Kumar P #include <fcntl.h> 14e2b8dc52SVenkata Suresh Kumar P #include <unistd.h> 15b77f6600SCristian Dumitrescu 16b77f6600SCristian Dumitrescu #include <rte_mempool.h> 17b77f6600SCristian Dumitrescu #include <rte_mbuf.h> 18b77f6600SCristian Dumitrescu #include <rte_ethdev.h> 19b77f6600SCristian Dumitrescu #include <rte_swx_port_ethdev.h> 20e2b8dc52SVenkata Suresh Kumar P #include <rte_swx_port_fd.h> 2177a41301SCristian Dumitrescu #include <rte_swx_port_ring.h> 22b77f6600SCristian Dumitrescu #include <rte_swx_port_source_sink.h> 23b77f6600SCristian Dumitrescu #include <rte_swx_table_em.h> 2466440b7bSCristian Dumitrescu #include <rte_swx_table_wm.h> 25b77f6600SCristian Dumitrescu #include <rte_swx_pipeline.h> 26b77f6600SCristian Dumitrescu #include <rte_swx_ctl.h> 27b77f6600SCristian Dumitrescu 28b77f6600SCristian Dumitrescu #include "obj.h" 29b77f6600SCristian Dumitrescu 30b77f6600SCristian Dumitrescu /* 31b77f6600SCristian Dumitrescu * mempool 32b77f6600SCristian Dumitrescu */ 33b77f6600SCristian Dumitrescu TAILQ_HEAD(mempool_list, mempool); 34b77f6600SCristian Dumitrescu 35b77f6600SCristian Dumitrescu /* 36b77f6600SCristian Dumitrescu * link 37b77f6600SCristian Dumitrescu */ 38b77f6600SCristian Dumitrescu TAILQ_HEAD(link_list, link); 39b77f6600SCristian Dumitrescu 40b77f6600SCristian Dumitrescu /* 4177a41301SCristian Dumitrescu * ring 4277a41301SCristian Dumitrescu */ 4377a41301SCristian Dumitrescu TAILQ_HEAD(ring_list, ring); 4477a41301SCristian Dumitrescu 4577a41301SCristian Dumitrescu /* 46e2b8dc52SVenkata Suresh Kumar P * tap 47e2b8dc52SVenkata Suresh Kumar P */ 48e2b8dc52SVenkata Suresh Kumar P TAILQ_HEAD(tap_list, tap); 49e2b8dc52SVenkata Suresh Kumar P 50e2b8dc52SVenkata Suresh Kumar P /* 51b77f6600SCristian Dumitrescu * pipeline 52b77f6600SCristian Dumitrescu */ 53b77f6600SCristian Dumitrescu TAILQ_HEAD(pipeline_list, pipeline); 54b77f6600SCristian Dumitrescu 55b77f6600SCristian Dumitrescu /* 56b77f6600SCristian Dumitrescu * obj 57b77f6600SCristian Dumitrescu */ 58b77f6600SCristian Dumitrescu struct obj { 59b77f6600SCristian Dumitrescu struct mempool_list mempool_list; 60b77f6600SCristian Dumitrescu struct link_list link_list; 6177a41301SCristian Dumitrescu struct ring_list ring_list; 62b77f6600SCristian Dumitrescu struct pipeline_list pipeline_list; 63e2b8dc52SVenkata Suresh Kumar P struct tap_list tap_list; 64b77f6600SCristian Dumitrescu }; 65b77f6600SCristian Dumitrescu 66b77f6600SCristian Dumitrescu /* 67b77f6600SCristian Dumitrescu * mempool 68b77f6600SCristian Dumitrescu */ 69b77f6600SCristian Dumitrescu #define BUFFER_SIZE_MIN (sizeof(struct rte_mbuf) + RTE_PKTMBUF_HEADROOM) 70b77f6600SCristian Dumitrescu 71b77f6600SCristian Dumitrescu struct mempool * 72b77f6600SCristian Dumitrescu mempool_create(struct obj *obj, const char *name, struct mempool_params *params) 73b77f6600SCristian Dumitrescu { 74b77f6600SCristian Dumitrescu struct mempool *mempool; 75b77f6600SCristian Dumitrescu struct rte_mempool *m; 76b77f6600SCristian Dumitrescu 77b77f6600SCristian Dumitrescu /* Check input params */ 78b77f6600SCristian Dumitrescu if ((name == NULL) || 79b77f6600SCristian Dumitrescu mempool_find(obj, name) || 80b77f6600SCristian Dumitrescu (params == NULL) || 81b77f6600SCristian Dumitrescu (params->buffer_size < BUFFER_SIZE_MIN) || 82b77f6600SCristian Dumitrescu (params->pool_size == 0)) 83b77f6600SCristian Dumitrescu return NULL; 84b77f6600SCristian Dumitrescu 85b77f6600SCristian Dumitrescu /* Resource create */ 86b77f6600SCristian Dumitrescu m = rte_pktmbuf_pool_create( 87b77f6600SCristian Dumitrescu name, 88b77f6600SCristian Dumitrescu params->pool_size, 89b77f6600SCristian Dumitrescu params->cache_size, 90b77f6600SCristian Dumitrescu 0, 91b77f6600SCristian Dumitrescu params->buffer_size - sizeof(struct rte_mbuf), 92b77f6600SCristian Dumitrescu params->cpu_id); 93b77f6600SCristian Dumitrescu 94b77f6600SCristian Dumitrescu if (m == NULL) 95b77f6600SCristian Dumitrescu return NULL; 96b77f6600SCristian Dumitrescu 97b77f6600SCristian Dumitrescu /* Node allocation */ 98b77f6600SCristian Dumitrescu mempool = calloc(1, sizeof(struct mempool)); 99b77f6600SCristian Dumitrescu if (mempool == NULL) { 100b77f6600SCristian Dumitrescu rte_mempool_free(m); 101b77f6600SCristian Dumitrescu return NULL; 102b77f6600SCristian Dumitrescu } 103b77f6600SCristian Dumitrescu 104b77f6600SCristian Dumitrescu /* Node fill in */ 105b77f6600SCristian Dumitrescu strlcpy(mempool->name, name, sizeof(mempool->name)); 106b77f6600SCristian Dumitrescu mempool->m = m; 107b77f6600SCristian Dumitrescu mempool->buffer_size = params->buffer_size; 108b77f6600SCristian Dumitrescu 109b77f6600SCristian Dumitrescu /* Node add to list */ 110b77f6600SCristian Dumitrescu TAILQ_INSERT_TAIL(&obj->mempool_list, mempool, node); 111b77f6600SCristian Dumitrescu 112b77f6600SCristian Dumitrescu return mempool; 113b77f6600SCristian Dumitrescu } 114b77f6600SCristian Dumitrescu 115b77f6600SCristian Dumitrescu struct mempool * 116b77f6600SCristian Dumitrescu mempool_find(struct obj *obj, const char *name) 117b77f6600SCristian Dumitrescu { 118b77f6600SCristian Dumitrescu struct mempool *mempool; 119b77f6600SCristian Dumitrescu 120b77f6600SCristian Dumitrescu if (!obj || !name) 121b77f6600SCristian Dumitrescu return NULL; 122b77f6600SCristian Dumitrescu 123b77f6600SCristian Dumitrescu TAILQ_FOREACH(mempool, &obj->mempool_list, node) 124b77f6600SCristian Dumitrescu if (strcmp(mempool->name, name) == 0) 125b77f6600SCristian Dumitrescu return mempool; 126b77f6600SCristian Dumitrescu 127b77f6600SCristian Dumitrescu return NULL; 128b77f6600SCristian Dumitrescu } 129b77f6600SCristian Dumitrescu 130b77f6600SCristian Dumitrescu /* 131b77f6600SCristian Dumitrescu * link 132b77f6600SCristian Dumitrescu */ 133b77f6600SCristian Dumitrescu static struct rte_eth_conf port_conf_default = { 134b77f6600SCristian Dumitrescu .link_speeds = 0, 135b77f6600SCristian Dumitrescu .rxmode = { 136b77f6600SCristian Dumitrescu .mq_mode = ETH_MQ_RX_NONE, 137*1bb4a528SFerruh Yigit .mtu = 9000 - (RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN), /* Jumbo frame MTU */ 138b77f6600SCristian Dumitrescu .split_hdr_size = 0, /* Header split buffer size */ 139b77f6600SCristian Dumitrescu }, 140b77f6600SCristian Dumitrescu .rx_adv_conf = { 141b77f6600SCristian Dumitrescu .rss_conf = { 142b77f6600SCristian Dumitrescu .rss_key = NULL, 143b77f6600SCristian Dumitrescu .rss_key_len = 40, 144b77f6600SCristian Dumitrescu .rss_hf = 0, 145b77f6600SCristian Dumitrescu }, 146b77f6600SCristian Dumitrescu }, 147b77f6600SCristian Dumitrescu .txmode = { 148b77f6600SCristian Dumitrescu .mq_mode = ETH_MQ_TX_NONE, 149b77f6600SCristian Dumitrescu }, 150b77f6600SCristian Dumitrescu .lpbk_mode = 0, 151b77f6600SCristian Dumitrescu }; 152b77f6600SCristian Dumitrescu 153b77f6600SCristian Dumitrescu #define RETA_CONF_SIZE (ETH_RSS_RETA_SIZE_512 / RTE_RETA_GROUP_SIZE) 154b77f6600SCristian Dumitrescu 155b77f6600SCristian Dumitrescu static int 156b77f6600SCristian Dumitrescu rss_setup(uint16_t port_id, 157b77f6600SCristian Dumitrescu uint16_t reta_size, 158b77f6600SCristian Dumitrescu struct link_params_rss *rss) 159b77f6600SCristian Dumitrescu { 160b77f6600SCristian Dumitrescu struct rte_eth_rss_reta_entry64 reta_conf[RETA_CONF_SIZE]; 161b77f6600SCristian Dumitrescu uint32_t i; 162b77f6600SCristian Dumitrescu int status; 163b77f6600SCristian Dumitrescu 164b77f6600SCristian Dumitrescu /* RETA setting */ 165b77f6600SCristian Dumitrescu memset(reta_conf, 0, sizeof(reta_conf)); 166b77f6600SCristian Dumitrescu 167b77f6600SCristian Dumitrescu for (i = 0; i < reta_size; i++) 168b77f6600SCristian Dumitrescu reta_conf[i / RTE_RETA_GROUP_SIZE].mask = UINT64_MAX; 169b77f6600SCristian Dumitrescu 170b77f6600SCristian Dumitrescu for (i = 0; i < reta_size; i++) { 171b77f6600SCristian Dumitrescu uint32_t reta_id = i / RTE_RETA_GROUP_SIZE; 172b77f6600SCristian Dumitrescu uint32_t reta_pos = i % RTE_RETA_GROUP_SIZE; 173b77f6600SCristian Dumitrescu uint32_t rss_qs_pos = i % rss->n_queues; 174b77f6600SCristian Dumitrescu 175b77f6600SCristian Dumitrescu reta_conf[reta_id].reta[reta_pos] = 176b77f6600SCristian Dumitrescu (uint16_t) rss->queue_id[rss_qs_pos]; 177b77f6600SCristian Dumitrescu } 178b77f6600SCristian Dumitrescu 179b77f6600SCristian Dumitrescu /* RETA update */ 180b77f6600SCristian Dumitrescu status = rte_eth_dev_rss_reta_update(port_id, 181b77f6600SCristian Dumitrescu reta_conf, 182b77f6600SCristian Dumitrescu reta_size); 183b77f6600SCristian Dumitrescu 184b77f6600SCristian Dumitrescu return status; 185b77f6600SCristian Dumitrescu } 186b77f6600SCristian Dumitrescu 187b77f6600SCristian Dumitrescu struct link * 188b77f6600SCristian Dumitrescu link_create(struct obj *obj, const char *name, struct link_params *params) 189b77f6600SCristian Dumitrescu { 190b77f6600SCristian Dumitrescu struct rte_eth_dev_info port_info; 191b77f6600SCristian Dumitrescu struct rte_eth_conf port_conf; 192b77f6600SCristian Dumitrescu struct link *link; 193b77f6600SCristian Dumitrescu struct link_params_rss *rss; 194b77f6600SCristian Dumitrescu struct mempool *mempool; 195b77f6600SCristian Dumitrescu uint32_t cpu_id, i; 196b77f6600SCristian Dumitrescu int status; 197b77f6600SCristian Dumitrescu uint16_t port_id; 198b77f6600SCristian Dumitrescu 199b77f6600SCristian Dumitrescu /* Check input params */ 200b77f6600SCristian Dumitrescu if ((name == NULL) || 201b77f6600SCristian Dumitrescu link_find(obj, name) || 202b77f6600SCristian Dumitrescu (params == NULL) || 203b77f6600SCristian Dumitrescu (params->rx.n_queues == 0) || 204b77f6600SCristian Dumitrescu (params->rx.queue_size == 0) || 205b77f6600SCristian Dumitrescu (params->tx.n_queues == 0) || 206b77f6600SCristian Dumitrescu (params->tx.queue_size == 0)) 207b77f6600SCristian Dumitrescu return NULL; 208b77f6600SCristian Dumitrescu 209b77f6600SCristian Dumitrescu port_id = params->port_id; 210b77f6600SCristian Dumitrescu if (params->dev_name) { 211b77f6600SCristian Dumitrescu status = rte_eth_dev_get_port_by_name(params->dev_name, 212b77f6600SCristian Dumitrescu &port_id); 213b77f6600SCristian Dumitrescu 214b77f6600SCristian Dumitrescu if (status) 215b77f6600SCristian Dumitrescu return NULL; 216b77f6600SCristian Dumitrescu } else 217b77f6600SCristian Dumitrescu if (!rte_eth_dev_is_valid_port(port_id)) 218b77f6600SCristian Dumitrescu return NULL; 219b77f6600SCristian Dumitrescu 220b77f6600SCristian Dumitrescu if (rte_eth_dev_info_get(port_id, &port_info) != 0) 221b77f6600SCristian Dumitrescu return NULL; 222b77f6600SCristian Dumitrescu 223b77f6600SCristian Dumitrescu mempool = mempool_find(obj, params->rx.mempool_name); 224b77f6600SCristian Dumitrescu if (mempool == NULL) 225b77f6600SCristian Dumitrescu return NULL; 226b77f6600SCristian Dumitrescu 227b77f6600SCristian Dumitrescu rss = params->rx.rss; 228b77f6600SCristian Dumitrescu if (rss) { 229b77f6600SCristian Dumitrescu if ((port_info.reta_size == 0) || 230b77f6600SCristian Dumitrescu (port_info.reta_size > ETH_RSS_RETA_SIZE_512)) 231b77f6600SCristian Dumitrescu return NULL; 232b77f6600SCristian Dumitrescu 233b77f6600SCristian Dumitrescu if ((rss->n_queues == 0) || 234b77f6600SCristian Dumitrescu (rss->n_queues >= LINK_RXQ_RSS_MAX)) 235b77f6600SCristian Dumitrescu return NULL; 236b77f6600SCristian Dumitrescu 237b77f6600SCristian Dumitrescu for (i = 0; i < rss->n_queues; i++) 238b77f6600SCristian Dumitrescu if (rss->queue_id[i] >= port_info.max_rx_queues) 239b77f6600SCristian Dumitrescu return NULL; 240b77f6600SCristian Dumitrescu } 241b77f6600SCristian Dumitrescu 242b77f6600SCristian Dumitrescu /** 243b77f6600SCristian Dumitrescu * Resource create 244b77f6600SCristian Dumitrescu */ 245b77f6600SCristian Dumitrescu /* Port */ 246b77f6600SCristian Dumitrescu memcpy(&port_conf, &port_conf_default, sizeof(port_conf)); 247b77f6600SCristian Dumitrescu if (rss) { 248b77f6600SCristian Dumitrescu port_conf.rxmode.mq_mode = ETH_MQ_RX_RSS; 249b77f6600SCristian Dumitrescu port_conf.rx_adv_conf.rss_conf.rss_hf = 250b77f6600SCristian Dumitrescu (ETH_RSS_IP | ETH_RSS_TCP | ETH_RSS_UDP) & 251b77f6600SCristian Dumitrescu port_info.flow_type_rss_offloads; 252b77f6600SCristian Dumitrescu } 253b77f6600SCristian Dumitrescu 254b77f6600SCristian Dumitrescu cpu_id = (uint32_t) rte_eth_dev_socket_id(port_id); 255b77f6600SCristian Dumitrescu if (cpu_id == (uint32_t) SOCKET_ID_ANY) 256b77f6600SCristian Dumitrescu cpu_id = 0; 257b77f6600SCristian Dumitrescu 258b77f6600SCristian Dumitrescu status = rte_eth_dev_configure( 259b77f6600SCristian Dumitrescu port_id, 260b77f6600SCristian Dumitrescu params->rx.n_queues, 261b77f6600SCristian Dumitrescu params->tx.n_queues, 262b77f6600SCristian Dumitrescu &port_conf); 263b77f6600SCristian Dumitrescu 264b77f6600SCristian Dumitrescu if (status < 0) 265b77f6600SCristian Dumitrescu return NULL; 266b77f6600SCristian Dumitrescu 267b77f6600SCristian Dumitrescu if (params->promiscuous) { 268b77f6600SCristian Dumitrescu status = rte_eth_promiscuous_enable(port_id); 269b77f6600SCristian Dumitrescu if (status != 0) 270b77f6600SCristian Dumitrescu return NULL; 271b77f6600SCristian Dumitrescu } 272b77f6600SCristian Dumitrescu 273b77f6600SCristian Dumitrescu /* Port RX */ 274b77f6600SCristian Dumitrescu for (i = 0; i < params->rx.n_queues; i++) { 275b77f6600SCristian Dumitrescu status = rte_eth_rx_queue_setup( 276b77f6600SCristian Dumitrescu port_id, 277b77f6600SCristian Dumitrescu i, 278b77f6600SCristian Dumitrescu params->rx.queue_size, 279b77f6600SCristian Dumitrescu cpu_id, 280b77f6600SCristian Dumitrescu NULL, 281b77f6600SCristian Dumitrescu mempool->m); 282b77f6600SCristian Dumitrescu 283b77f6600SCristian Dumitrescu if (status < 0) 284b77f6600SCristian Dumitrescu return NULL; 285b77f6600SCristian Dumitrescu } 286b77f6600SCristian Dumitrescu 287b77f6600SCristian Dumitrescu /* Port TX */ 288b77f6600SCristian Dumitrescu for (i = 0; i < params->tx.n_queues; i++) { 289b77f6600SCristian Dumitrescu status = rte_eth_tx_queue_setup( 290b77f6600SCristian Dumitrescu port_id, 291b77f6600SCristian Dumitrescu i, 292b77f6600SCristian Dumitrescu params->tx.queue_size, 293b77f6600SCristian Dumitrescu cpu_id, 294b77f6600SCristian Dumitrescu NULL); 295b77f6600SCristian Dumitrescu 296b77f6600SCristian Dumitrescu if (status < 0) 297b77f6600SCristian Dumitrescu return NULL; 298b77f6600SCristian Dumitrescu } 299b77f6600SCristian Dumitrescu 300b77f6600SCristian Dumitrescu /* Port start */ 301b77f6600SCristian Dumitrescu status = rte_eth_dev_start(port_id); 302b77f6600SCristian Dumitrescu if (status < 0) 303b77f6600SCristian Dumitrescu return NULL; 304b77f6600SCristian Dumitrescu 305b77f6600SCristian Dumitrescu if (rss) { 306b77f6600SCristian Dumitrescu status = rss_setup(port_id, port_info.reta_size, rss); 307b77f6600SCristian Dumitrescu 308b77f6600SCristian Dumitrescu if (status) { 309b77f6600SCristian Dumitrescu rte_eth_dev_stop(port_id); 310b77f6600SCristian Dumitrescu return NULL; 311b77f6600SCristian Dumitrescu } 312b77f6600SCristian Dumitrescu } 313b77f6600SCristian Dumitrescu 314b77f6600SCristian Dumitrescu /* Port link up */ 315b77f6600SCristian Dumitrescu status = rte_eth_dev_set_link_up(port_id); 316b77f6600SCristian Dumitrescu if ((status < 0) && (status != -ENOTSUP)) { 317b77f6600SCristian Dumitrescu rte_eth_dev_stop(port_id); 318b77f6600SCristian Dumitrescu return NULL; 319b77f6600SCristian Dumitrescu } 320b77f6600SCristian Dumitrescu 321b77f6600SCristian Dumitrescu /* Node allocation */ 322b77f6600SCristian Dumitrescu link = calloc(1, sizeof(struct link)); 323b77f6600SCristian Dumitrescu if (link == NULL) { 324b77f6600SCristian Dumitrescu rte_eth_dev_stop(port_id); 325b77f6600SCristian Dumitrescu return NULL; 326b77f6600SCristian Dumitrescu } 327b77f6600SCristian Dumitrescu 328b77f6600SCristian Dumitrescu /* Node fill in */ 329b77f6600SCristian Dumitrescu strlcpy(link->name, name, sizeof(link->name)); 330b77f6600SCristian Dumitrescu link->port_id = port_id; 331b77f6600SCristian Dumitrescu rte_eth_dev_get_name_by_port(port_id, link->dev_name); 332b77f6600SCristian Dumitrescu link->n_rxq = params->rx.n_queues; 333b77f6600SCristian Dumitrescu link->n_txq = params->tx.n_queues; 334b77f6600SCristian Dumitrescu 335b77f6600SCristian Dumitrescu /* Node add to list */ 336b77f6600SCristian Dumitrescu TAILQ_INSERT_TAIL(&obj->link_list, link, node); 337b77f6600SCristian Dumitrescu 338b77f6600SCristian Dumitrescu return link; 339b77f6600SCristian Dumitrescu } 340b77f6600SCristian Dumitrescu 341b77f6600SCristian Dumitrescu int 342b77f6600SCristian Dumitrescu link_is_up(struct obj *obj, const char *name) 343b77f6600SCristian Dumitrescu { 344b77f6600SCristian Dumitrescu struct rte_eth_link link_params; 345b77f6600SCristian Dumitrescu struct link *link; 346b77f6600SCristian Dumitrescu 347b77f6600SCristian Dumitrescu /* Check input params */ 348b77f6600SCristian Dumitrescu if (!obj || !name) 349b77f6600SCristian Dumitrescu return 0; 350b77f6600SCristian Dumitrescu 351b77f6600SCristian Dumitrescu link = link_find(obj, name); 352b77f6600SCristian Dumitrescu if (link == NULL) 353b77f6600SCristian Dumitrescu return 0; 354b77f6600SCristian Dumitrescu 355b77f6600SCristian Dumitrescu /* Resource */ 356b77f6600SCristian Dumitrescu if (rte_eth_link_get(link->port_id, &link_params) < 0) 357b77f6600SCristian Dumitrescu return 0; 358b77f6600SCristian Dumitrescu 359b77f6600SCristian Dumitrescu return (link_params.link_status == ETH_LINK_DOWN) ? 0 : 1; 360b77f6600SCristian Dumitrescu } 361b77f6600SCristian Dumitrescu 362b77f6600SCristian Dumitrescu struct link * 363b77f6600SCristian Dumitrescu link_find(struct obj *obj, const char *name) 364b77f6600SCristian Dumitrescu { 365b77f6600SCristian Dumitrescu struct link *link; 366b77f6600SCristian Dumitrescu 367b77f6600SCristian Dumitrescu if (!obj || !name) 368b77f6600SCristian Dumitrescu return NULL; 369b77f6600SCristian Dumitrescu 370b77f6600SCristian Dumitrescu TAILQ_FOREACH(link, &obj->link_list, node) 371b77f6600SCristian Dumitrescu if (strcmp(link->name, name) == 0) 372b77f6600SCristian Dumitrescu return link; 373b77f6600SCristian Dumitrescu 374b77f6600SCristian Dumitrescu return NULL; 375b77f6600SCristian Dumitrescu } 376b77f6600SCristian Dumitrescu 377b77f6600SCristian Dumitrescu struct link * 378b77f6600SCristian Dumitrescu link_next(struct obj *obj, struct link *link) 379b77f6600SCristian Dumitrescu { 380b77f6600SCristian Dumitrescu return (link == NULL) ? 381b77f6600SCristian Dumitrescu TAILQ_FIRST(&obj->link_list) : TAILQ_NEXT(link, node); 382b77f6600SCristian Dumitrescu } 383b77f6600SCristian Dumitrescu 384b77f6600SCristian Dumitrescu /* 38577a41301SCristian Dumitrescu * ring 38677a41301SCristian Dumitrescu */ 38777a41301SCristian Dumitrescu struct ring * 38877a41301SCristian Dumitrescu ring_create(struct obj *obj, const char *name, struct ring_params *params) 38977a41301SCristian Dumitrescu { 39077a41301SCristian Dumitrescu struct ring *ring; 39177a41301SCristian Dumitrescu struct rte_ring *r; 39277a41301SCristian Dumitrescu unsigned int flags = RING_F_SP_ENQ | RING_F_SC_DEQ; 39377a41301SCristian Dumitrescu 39477a41301SCristian Dumitrescu /* Check input params */ 39577a41301SCristian Dumitrescu if (!name || ring_find(obj, name) || !params || !params->size) 39677a41301SCristian Dumitrescu return NULL; 39777a41301SCristian Dumitrescu 39877a41301SCristian Dumitrescu /** 39977a41301SCristian Dumitrescu * Resource create 40077a41301SCristian Dumitrescu */ 40177a41301SCristian Dumitrescu r = rte_ring_create( 40277a41301SCristian Dumitrescu name, 40377a41301SCristian Dumitrescu params->size, 40477a41301SCristian Dumitrescu params->numa_node, 40577a41301SCristian Dumitrescu flags); 40677a41301SCristian Dumitrescu if (!r) 40777a41301SCristian Dumitrescu return NULL; 40877a41301SCristian Dumitrescu 40977a41301SCristian Dumitrescu /* Node allocation */ 41077a41301SCristian Dumitrescu ring = calloc(1, sizeof(struct ring)); 41177a41301SCristian Dumitrescu if (!ring) { 41277a41301SCristian Dumitrescu rte_ring_free(r); 41377a41301SCristian Dumitrescu return NULL; 41477a41301SCristian Dumitrescu } 41577a41301SCristian Dumitrescu 41677a41301SCristian Dumitrescu /* Node fill in */ 41777a41301SCristian Dumitrescu strlcpy(ring->name, name, sizeof(ring->name)); 41877a41301SCristian Dumitrescu 41977a41301SCristian Dumitrescu /* Node add to list */ 42077a41301SCristian Dumitrescu TAILQ_INSERT_TAIL(&obj->ring_list, ring, node); 42177a41301SCristian Dumitrescu 42277a41301SCristian Dumitrescu return ring; 42377a41301SCristian Dumitrescu } 42477a41301SCristian Dumitrescu 42577a41301SCristian Dumitrescu struct ring * 42677a41301SCristian Dumitrescu ring_find(struct obj *obj, const char *name) 42777a41301SCristian Dumitrescu { 42877a41301SCristian Dumitrescu struct ring *ring; 42977a41301SCristian Dumitrescu 43077a41301SCristian Dumitrescu if (!obj || !name) 43177a41301SCristian Dumitrescu return NULL; 43277a41301SCristian Dumitrescu 43377a41301SCristian Dumitrescu TAILQ_FOREACH(ring, &obj->ring_list, node) 43477a41301SCristian Dumitrescu if (strcmp(ring->name, name) == 0) 43577a41301SCristian Dumitrescu return ring; 43677a41301SCristian Dumitrescu 43777a41301SCristian Dumitrescu return NULL; 43877a41301SCristian Dumitrescu } 43977a41301SCristian Dumitrescu 44077a41301SCristian Dumitrescu /* 441e2b8dc52SVenkata Suresh Kumar P * tap 442e2b8dc52SVenkata Suresh Kumar P */ 443e2b8dc52SVenkata Suresh Kumar P #define TAP_DEV "/dev/net/tun" 444e2b8dc52SVenkata Suresh Kumar P 445e2b8dc52SVenkata Suresh Kumar P struct tap * 446e2b8dc52SVenkata Suresh Kumar P tap_find(struct obj *obj, const char *name) 447e2b8dc52SVenkata Suresh Kumar P { 448e2b8dc52SVenkata Suresh Kumar P struct tap *tap; 449e2b8dc52SVenkata Suresh Kumar P 450e2b8dc52SVenkata Suresh Kumar P if (!obj || !name) 451e2b8dc52SVenkata Suresh Kumar P return NULL; 452e2b8dc52SVenkata Suresh Kumar P 453e2b8dc52SVenkata Suresh Kumar P TAILQ_FOREACH(tap, &obj->tap_list, node) 454e2b8dc52SVenkata Suresh Kumar P if (strcmp(tap->name, name) == 0) 455e2b8dc52SVenkata Suresh Kumar P return tap; 456e2b8dc52SVenkata Suresh Kumar P 457e2b8dc52SVenkata Suresh Kumar P return NULL; 458e2b8dc52SVenkata Suresh Kumar P } 459e2b8dc52SVenkata Suresh Kumar P 460e2b8dc52SVenkata Suresh Kumar P struct tap * 461e2b8dc52SVenkata Suresh Kumar P tap_next(struct obj *obj, struct tap *tap) 462e2b8dc52SVenkata Suresh Kumar P { 463e2b8dc52SVenkata Suresh Kumar P return (tap == NULL) ? 464e2b8dc52SVenkata Suresh Kumar P TAILQ_FIRST(&obj->tap_list) : TAILQ_NEXT(tap, node); 465e2b8dc52SVenkata Suresh Kumar P } 466e2b8dc52SVenkata Suresh Kumar P 467e2b8dc52SVenkata Suresh Kumar P #ifndef RTE_EXEC_ENV_LINUX 468e2b8dc52SVenkata Suresh Kumar P 469e2b8dc52SVenkata Suresh Kumar P struct tap * 470e2b8dc52SVenkata Suresh Kumar P tap_create(struct obj *obj __rte_unused, const char *name __rte_unused) 471e2b8dc52SVenkata Suresh Kumar P { 472e2b8dc52SVenkata Suresh Kumar P return NULL; 473e2b8dc52SVenkata Suresh Kumar P } 474e2b8dc52SVenkata Suresh Kumar P 475e2b8dc52SVenkata Suresh Kumar P #else 476e2b8dc52SVenkata Suresh Kumar P 477e2b8dc52SVenkata Suresh Kumar P struct tap * 478e2b8dc52SVenkata Suresh Kumar P tap_create(struct obj *obj, const char *name) 479e2b8dc52SVenkata Suresh Kumar P { 480e2b8dc52SVenkata Suresh Kumar P struct tap *tap; 481e2b8dc52SVenkata Suresh Kumar P struct ifreq ifr; 482e2b8dc52SVenkata Suresh Kumar P int fd, status; 483e2b8dc52SVenkata Suresh Kumar P 484e2b8dc52SVenkata Suresh Kumar P /* Check input params */ 485e2b8dc52SVenkata Suresh Kumar P if ((name == NULL) || 486e2b8dc52SVenkata Suresh Kumar P tap_find(obj, name)) 487e2b8dc52SVenkata Suresh Kumar P return NULL; 488e2b8dc52SVenkata Suresh Kumar P 489e2b8dc52SVenkata Suresh Kumar P /* Resource create */ 490e2b8dc52SVenkata Suresh Kumar P fd = open(TAP_DEV, O_RDWR | O_NONBLOCK); 491e2b8dc52SVenkata Suresh Kumar P if (fd < 0) 492e2b8dc52SVenkata Suresh Kumar P return NULL; 493e2b8dc52SVenkata Suresh Kumar P 494e2b8dc52SVenkata Suresh Kumar P memset(&ifr, 0, sizeof(ifr)); 495e2b8dc52SVenkata Suresh Kumar P ifr.ifr_flags = IFF_TAP | IFF_NO_PI; /* No packet information */ 496e2b8dc52SVenkata Suresh Kumar P strlcpy(ifr.ifr_name, name, IFNAMSIZ); 497e2b8dc52SVenkata Suresh Kumar P 498e2b8dc52SVenkata Suresh Kumar P status = ioctl(fd, TUNSETIFF, (void *) &ifr); 499e2b8dc52SVenkata Suresh Kumar P if (status < 0) { 500e2b8dc52SVenkata Suresh Kumar P close(fd); 501e2b8dc52SVenkata Suresh Kumar P return NULL; 502e2b8dc52SVenkata Suresh Kumar P } 503e2b8dc52SVenkata Suresh Kumar P 504e2b8dc52SVenkata Suresh Kumar P /* Node allocation */ 505e2b8dc52SVenkata Suresh Kumar P tap = calloc(1, sizeof(struct tap)); 506e2b8dc52SVenkata Suresh Kumar P if (tap == NULL) { 507e2b8dc52SVenkata Suresh Kumar P close(fd); 508e2b8dc52SVenkata Suresh Kumar P return NULL; 509e2b8dc52SVenkata Suresh Kumar P } 510e2b8dc52SVenkata Suresh Kumar P /* Node fill in */ 511e2b8dc52SVenkata Suresh Kumar P strlcpy(tap->name, name, sizeof(tap->name)); 512e2b8dc52SVenkata Suresh Kumar P tap->fd = fd; 513e2b8dc52SVenkata Suresh Kumar P 514e2b8dc52SVenkata Suresh Kumar P /* Node add to list */ 515e2b8dc52SVenkata Suresh Kumar P TAILQ_INSERT_TAIL(&obj->tap_list, tap, node); 516e2b8dc52SVenkata Suresh Kumar P 517e2b8dc52SVenkata Suresh Kumar P return tap; 518e2b8dc52SVenkata Suresh Kumar P } 519e2b8dc52SVenkata Suresh Kumar P 520e2b8dc52SVenkata Suresh Kumar P #endif 521e2b8dc52SVenkata Suresh Kumar P 522e2b8dc52SVenkata Suresh Kumar P /* 523b77f6600SCristian Dumitrescu * pipeline 524b77f6600SCristian Dumitrescu */ 525b77f6600SCristian Dumitrescu #ifndef PIPELINE_MSGQ_SIZE 526b77f6600SCristian Dumitrescu #define PIPELINE_MSGQ_SIZE 64 527b77f6600SCristian Dumitrescu #endif 528b77f6600SCristian Dumitrescu 529b77f6600SCristian Dumitrescu struct pipeline * 530b77f6600SCristian Dumitrescu pipeline_create(struct obj *obj, const char *name, int numa_node) 531b77f6600SCristian Dumitrescu { 532b77f6600SCristian Dumitrescu struct pipeline *pipeline; 533b77f6600SCristian Dumitrescu struct rte_swx_pipeline *p = NULL; 534b77f6600SCristian Dumitrescu int status; 535b77f6600SCristian Dumitrescu 536b77f6600SCristian Dumitrescu /* Check input params */ 537b77f6600SCristian Dumitrescu if ((name == NULL) || 538b77f6600SCristian Dumitrescu pipeline_find(obj, name)) 539b77f6600SCristian Dumitrescu return NULL; 540b77f6600SCristian Dumitrescu 541b77f6600SCristian Dumitrescu /* Resource create */ 542b77f6600SCristian Dumitrescu status = rte_swx_pipeline_config(&p, numa_node); 543b77f6600SCristian Dumitrescu if (status) 544b77f6600SCristian Dumitrescu goto error; 545b77f6600SCristian Dumitrescu 546b77f6600SCristian Dumitrescu status = rte_swx_pipeline_port_in_type_register(p, 547b77f6600SCristian Dumitrescu "ethdev", 548b77f6600SCristian Dumitrescu &rte_swx_port_ethdev_reader_ops); 549b77f6600SCristian Dumitrescu if (status) 550b77f6600SCristian Dumitrescu goto error; 551b77f6600SCristian Dumitrescu 552b77f6600SCristian Dumitrescu status = rte_swx_pipeline_port_out_type_register(p, 553b77f6600SCristian Dumitrescu "ethdev", 554b77f6600SCristian Dumitrescu &rte_swx_port_ethdev_writer_ops); 555b77f6600SCristian Dumitrescu if (status) 556b77f6600SCristian Dumitrescu goto error; 557b77f6600SCristian Dumitrescu 55877a41301SCristian Dumitrescu status = rte_swx_pipeline_port_in_type_register(p, 55977a41301SCristian Dumitrescu "ring", 56077a41301SCristian Dumitrescu &rte_swx_port_ring_reader_ops); 56177a41301SCristian Dumitrescu if (status) 56277a41301SCristian Dumitrescu goto error; 56377a41301SCristian Dumitrescu 56477a41301SCristian Dumitrescu status = rte_swx_pipeline_port_out_type_register(p, 56577a41301SCristian Dumitrescu "ring", 56677a41301SCristian Dumitrescu &rte_swx_port_ring_writer_ops); 56777a41301SCristian Dumitrescu if (status) 56877a41301SCristian Dumitrescu goto error; 56977a41301SCristian Dumitrescu 570b77f6600SCristian Dumitrescu #ifdef RTE_PORT_PCAP 571b77f6600SCristian Dumitrescu status = rte_swx_pipeline_port_in_type_register(p, 572b77f6600SCristian Dumitrescu "source", 573b77f6600SCristian Dumitrescu &rte_swx_port_source_ops); 574b77f6600SCristian Dumitrescu if (status) 575b77f6600SCristian Dumitrescu goto error; 576b77f6600SCristian Dumitrescu #endif 577b77f6600SCristian Dumitrescu 578b77f6600SCristian Dumitrescu status = rte_swx_pipeline_port_out_type_register(p, 579b77f6600SCristian Dumitrescu "sink", 580b77f6600SCristian Dumitrescu &rte_swx_port_sink_ops); 581b77f6600SCristian Dumitrescu if (status) 582b77f6600SCristian Dumitrescu goto error; 583b77f6600SCristian Dumitrescu 584e2b8dc52SVenkata Suresh Kumar P status = rte_swx_pipeline_port_in_type_register(p, 585e2b8dc52SVenkata Suresh Kumar P "fd", 586e2b8dc52SVenkata Suresh Kumar P &rte_swx_port_fd_reader_ops); 587e2b8dc52SVenkata Suresh Kumar P if (status) 588e2b8dc52SVenkata Suresh Kumar P goto error; 589e2b8dc52SVenkata Suresh Kumar P 590e2b8dc52SVenkata Suresh Kumar P status = rte_swx_pipeline_port_out_type_register(p, 591e2b8dc52SVenkata Suresh Kumar P "fd", 592e2b8dc52SVenkata Suresh Kumar P &rte_swx_port_fd_writer_ops); 593e2b8dc52SVenkata Suresh Kumar P if (status) 594e2b8dc52SVenkata Suresh Kumar P goto error; 595e2b8dc52SVenkata Suresh Kumar P 596b77f6600SCristian Dumitrescu status = rte_swx_pipeline_table_type_register(p, 597b77f6600SCristian Dumitrescu "exact", 598b77f6600SCristian Dumitrescu RTE_SWX_TABLE_MATCH_EXACT, 599b77f6600SCristian Dumitrescu &rte_swx_table_exact_match_ops); 600b77f6600SCristian Dumitrescu if (status) 601b77f6600SCristian Dumitrescu goto error; 602b77f6600SCristian Dumitrescu 60366440b7bSCristian Dumitrescu status = rte_swx_pipeline_table_type_register(p, 60466440b7bSCristian Dumitrescu "wildcard", 60566440b7bSCristian Dumitrescu RTE_SWX_TABLE_MATCH_WILDCARD, 60666440b7bSCristian Dumitrescu &rte_swx_table_wildcard_match_ops); 60766440b7bSCristian Dumitrescu if (status) 60866440b7bSCristian Dumitrescu goto error; 60966440b7bSCristian Dumitrescu 610b77f6600SCristian Dumitrescu /* Node allocation */ 611b77f6600SCristian Dumitrescu pipeline = calloc(1, sizeof(struct pipeline)); 612b77f6600SCristian Dumitrescu if (pipeline == NULL) 613b77f6600SCristian Dumitrescu goto error; 614b77f6600SCristian Dumitrescu 615b77f6600SCristian Dumitrescu /* Node fill in */ 616b77f6600SCristian Dumitrescu strlcpy(pipeline->name, name, sizeof(pipeline->name)); 617b77f6600SCristian Dumitrescu pipeline->p = p; 618b77f6600SCristian Dumitrescu pipeline->timer_period_ms = 10; 619b77f6600SCristian Dumitrescu 620b77f6600SCristian Dumitrescu /* Node add to list */ 621b77f6600SCristian Dumitrescu TAILQ_INSERT_TAIL(&obj->pipeline_list, pipeline, node); 622b77f6600SCristian Dumitrescu 623b77f6600SCristian Dumitrescu return pipeline; 624b77f6600SCristian Dumitrescu 625b77f6600SCristian Dumitrescu error: 626b77f6600SCristian Dumitrescu rte_swx_pipeline_free(p); 627b77f6600SCristian Dumitrescu return NULL; 628b77f6600SCristian Dumitrescu } 629b77f6600SCristian Dumitrescu 630b77f6600SCristian Dumitrescu struct pipeline * 631b77f6600SCristian Dumitrescu pipeline_find(struct obj *obj, const char *name) 632b77f6600SCristian Dumitrescu { 633b77f6600SCristian Dumitrescu struct pipeline *pipeline; 634b77f6600SCristian Dumitrescu 635b77f6600SCristian Dumitrescu if (!obj || !name) 636b77f6600SCristian Dumitrescu return NULL; 637b77f6600SCristian Dumitrescu 638b77f6600SCristian Dumitrescu TAILQ_FOREACH(pipeline, &obj->pipeline_list, node) 639b77f6600SCristian Dumitrescu if (strcmp(name, pipeline->name) == 0) 640b77f6600SCristian Dumitrescu return pipeline; 641b77f6600SCristian Dumitrescu 642b77f6600SCristian Dumitrescu return NULL; 643b77f6600SCristian Dumitrescu } 644b77f6600SCristian Dumitrescu 645b77f6600SCristian Dumitrescu /* 646b77f6600SCristian Dumitrescu * obj 647b77f6600SCristian Dumitrescu */ 648b77f6600SCristian Dumitrescu struct obj * 649b77f6600SCristian Dumitrescu obj_init(void) 650b77f6600SCristian Dumitrescu { 651b77f6600SCristian Dumitrescu struct obj *obj; 652b77f6600SCristian Dumitrescu 653b77f6600SCristian Dumitrescu obj = calloc(1, sizeof(struct obj)); 654b77f6600SCristian Dumitrescu if (!obj) 655b77f6600SCristian Dumitrescu return NULL; 656b77f6600SCristian Dumitrescu 657b77f6600SCristian Dumitrescu TAILQ_INIT(&obj->mempool_list); 658b77f6600SCristian Dumitrescu TAILQ_INIT(&obj->link_list); 65977a41301SCristian Dumitrescu TAILQ_INIT(&obj->ring_list); 660b77f6600SCristian Dumitrescu TAILQ_INIT(&obj->pipeline_list); 661e2b8dc52SVenkata Suresh Kumar P TAILQ_INIT(&obj->tap_list); 662b77f6600SCristian Dumitrescu 663b77f6600SCristian Dumitrescu return obj; 664b77f6600SCristian Dumitrescu } 665