2 // Copyright (c) 2010-2020 Intel Corporation
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
8 // http://www.apache.org/licenses/LICENSE-2.0
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
19 #include <rte_version.h>
20 #include <rte_eth_ring.h>
22 #if (RTE_VERSION >= RTE_VERSION_NUM(17,11,0,0))
23 #include <rte_bus_vdev.h>
25 #if (RTE_VERSION > RTE_VERSION_NUM(17,5,0,2))
28 #if (RTE_VERSION >= RTE_VERSION_NUM(2,1,0,0))
29 #include <rte_eth_null.h>
34 #include <sys/ioctl.h>
37 #include "prox_port_cfg.h"
38 #include "prox_globals.h"
44 #include "prox_cksum.h"
45 #include "stats_irq.h"
46 #include "prox_compat.h"
47 #include "rte_ethdev.h"
50 struct prox_port_cfg prox_port_cfg[PROX_MAX_PORTS];
54 int prox_nb_active_ports(void)
57 for (uint32_t i = 0; i < PROX_MAX_PORTS; ++i) {
58 ret += prox_port_cfg[i].active;
63 int prox_last_port_active(void)
66 for (uint32_t i = 0; i < PROX_MAX_PORTS; ++i) {
67 if (prox_port_cfg[i].active) {
74 #if RTE_VERSION >= RTE_VERSION_NUM(17,11,0,0)
75 static int lsc_cb(__attribute__((unused)) uint16_t port_id, enum rte_eth_event_type type, __attribute__((unused)) void *param,
76 __attribute__((unused)) void *ret_param)
78 #if RTE_VERSION >= RTE_VERSION_NUM(17,8,0,1)
79 static int lsc_cb(__attribute__((unused)) uint8_t port_id, enum rte_eth_event_type type, __attribute__((unused)) void *param,
80 __attribute__((unused)) void *ret_param)
82 static void lsc_cb(__attribute__((unused)) uint8_t port_id, enum rte_eth_event_type type, __attribute__((unused)) void *param)
86 if (RTE_ETH_EVENT_INTR_LSC != type) {
87 #if RTE_VERSION >= RTE_VERSION_NUM(17,8,0,1)
94 rte_atomic32_inc(&lsc);
96 #if RTE_VERSION >= RTE_VERSION_NUM(17,8,0,1)
101 struct prox_pktmbuf_reinit_args {
102 struct rte_mempool *mp;
103 struct lcore_cfg *lconf;
106 /* standard mbuf initialization procedure */
107 void prox_pktmbuf_init(struct rte_mempool *mp, void *opaque_arg, void *_m, unsigned i)
109 struct rte_mbuf *mbuf = _m;
111 #if RTE_VERSION >= RTE_VERSION_NUM(1,8,0,0)
112 mbuf->tx_offload = CALC_TX_OL(sizeof(prox_rte_ether_hdr), sizeof(prox_rte_ipv4_hdr));
114 mbuf->pkt.vlan_macip.f.l2_len = sizeof(prox_rte_ether_hdr);
115 mbuf->pkt.vlan_macip.f.l3_len = sizeof(prox_rte_ipv4_hdr);
118 rte_pktmbuf_init(mp, opaque_arg, mbuf, i);
121 void prox_pktmbuf_reinit(void *arg, void *start, __attribute__((unused)) void *end, uint32_t idx)
123 struct prox_pktmbuf_reinit_args *init_args = arg;
127 obj += init_args->mp->header_size;
128 m = (struct rte_mbuf*)obj;
130 prox_pktmbuf_init(init_args->mp, init_args->lconf, obj, idx);
133 #define CONFIGURE_TX_OFFLOAD(flag) \
134 if (port_cfg->requested_tx_offload & flag) {\
135 if (port_cfg->disabled_tx_offload & flag) {\
136 plog_info("\t\t%s disabled by configuration\n", #flag);\
137 port_cfg->requested_tx_offload &= ~flag;\
138 } else if (port_cfg->dev_info.tx_offload_capa & flag) {\
139 port_cfg->port_conf.txmode.offloads |= flag;\
140 plog_info("\t\t%s enabled on port\n", #flag);\
141 } else if (port_cfg->dev_info.tx_queue_offload_capa & flag) {\
142 port_cfg->tx_conf.offloads |= flag;\
143 plog_info("\t\t%s enabled on queue\n", #flag);\
145 port_cfg->requested_tx_offload &= ~flag;\
146 plog_info("\t\t%s disabled as neither port or queue supports it\n", #flag);\
149 plog_info("\t\t%s disabled\n", #flag);\
152 #define CONFIGURE_RX_OFFLOAD(flag) \
153 if (port_cfg->requested_rx_offload & flag) {\
154 if (port_cfg->dev_info.rx_offload_capa & flag) {\
155 port_cfg->port_conf.rxmode.offloads |= flag;\
156 plog_info("\t\t%s enabled on port\n", #flag);\
157 } else if (port_cfg->dev_info.rx_queue_offload_capa & flag) {\
158 port_cfg->rx_conf.offloads |= flag;\
159 plog_info("\t\t%s enabled on queue\n", #flag);\
161 port_cfg->requested_rx_offload &= ~flag;\
162 plog_info("\t\t%s disabled as neither port or queue supports it\n", #flag);\
165 plog_info("\t\t%s disabled\n", #flag);\
168 static inline uint32_t get_netmask(uint8_t prefix)
171 return(~((uint32_t) -1));
173 return rte_cpu_to_be_32(~((1 << (32 - prefix)) - 1));
176 static void set_ip_address(char *devname, uint32_t *ip, uint8_t prefix)
179 struct sockaddr_in in_addr;
181 uint32_t netmask = get_netmask(prefix);
182 plog_info("Setting netmask to %x\n", netmask);
184 fd = socket(AF_INET, SOCK_DGRAM, 0);
186 memset(&ifreq, 0, sizeof(struct ifreq));
187 memset(&in_addr, 0, sizeof(struct sockaddr_in));
189 in_addr.sin_family = AF_INET;
190 in_addr.sin_addr = *(struct in_addr *)ip;
192 strncpy(ifreq.ifr_name, devname, IFNAMSIZ);
193 ifreq.ifr_addr = *(struct sockaddr *)&in_addr;
194 rc = ioctl(fd, SIOCSIFADDR, &ifreq);
195 PROX_PANIC(rc < 0, "Failed to set IP address %x on device %s: error = %d (%s)\n", *ip, devname, errno, strerror(errno));
197 in_addr.sin_addr = *(struct in_addr *)&netmask;
198 ifreq.ifr_netmask = *(struct sockaddr *)&in_addr;
199 rc = ioctl(fd, SIOCSIFNETMASK, &ifreq);
200 PROX_PANIC(rc < 0, "Failed to set netmask %x (prefix %d) on device %s: error = %d (%s)\n", netmask, prefix, devname, errno, strerror(errno));
204 /* initialize rte devices and check the number of available ports */
205 void init_rte_dev(int use_dummy_devices)
207 uint8_t nb_ports, port_id_max;
208 int port_id_last, rc = 0;
209 struct rte_eth_dev_info dev_info;
210 const struct rte_pci_device *pci_dev;
212 for (uint8_t port_id = 0; port_id < PROX_MAX_PORTS; ++port_id) {
213 if (!prox_port_cfg[port_id].active) {
216 struct prox_port_cfg* port_cfg = &prox_port_cfg[port_id];
218 prox_port_cfg[port_id].n_vlans = 0;
219 while ((prox_port_cfg[port_id].n_vlans < PROX_MAX_VLAN_TAGS) && (prox_port_cfg[port_id].vlan_tags[prox_port_cfg[port_id].n_vlans])) {
220 prox_port_cfg[port_id].n_vlans++;
223 if (port_cfg->vdev[0]) {
224 char name[MAX_NAME_SIZE], tap[MAX_NAME_SIZE];
225 snprintf(tap, MAX_NAME_SIZE, "net_tap%d", port_id);
226 #if (RTE_VERSION > RTE_VERSION_NUM(17,5,0,1))
227 snprintf(name, MAX_NAME_SIZE, "iface=%s", port_cfg->vdev);
228 rc = rte_vdev_init(tap, name);
230 PROX_PANIC(1, "vdev not supported in DPDK < 17.05\n");
232 PROX_PANIC(rc != 0, "Unable to create device %s %s\n", "net tap", port_cfg->vdev);
233 int vdev_port_id = prox_rte_eth_dev_count_avail() - 1;
234 PROX_PANIC(vdev_port_id >= PROX_MAX_PORTS, "Too many port defined %d >= %d\n", vdev_port_id, PROX_MAX_PORTS);
235 plog_info("\tCreating device %s, port %d\n", port_cfg->vdev, vdev_port_id);
236 prox_port_cfg[vdev_port_id].is_vdev = 1;
237 prox_port_cfg[vdev_port_id].active = 1;
238 prox_port_cfg[vdev_port_id].dpdk_mapping = port_id;
239 prox_port_cfg[vdev_port_id].n_txq = 1;
240 prox_port_cfg[vdev_port_id].n_vlans = prox_port_cfg[port_id].n_vlans;
242 for (uint32_t tag_id = 0; tag_id < prox_port_cfg[port_id].n_vlans; tag_id++) {
243 prox_port_cfg[vdev_port_id].vlan_tags[tag_id] = prox_port_cfg[port_id].vlan_tags[tag_id];
245 snprintf(prox_port_cfg[vdev_port_id].names[tag_id], MAX_NAME_SIZE, "%s_%d", port_cfg->vdev, prox_port_cfg[port_id].vlan_tags[tag_id]);
246 sprintf(command, "ip link add link %s name %s type vlan id %d", port_cfg->vdev, prox_port_cfg[vdev_port_id].names[tag_id], prox_port_cfg[port_id].vlan_tags[tag_id]);
248 plog_info("\tRunning %s\n", command);
249 plog_info("\tUsing vlan tag %d - added device %s\n", prox_port_cfg[port_id].vlan_tags[tag_id], prox_port_cfg[vdev_port_id].names[tag_id]);
251 if (prox_port_cfg[port_id].n_vlans == 0) {
252 strncpy(prox_port_cfg[vdev_port_id].names[0], port_cfg->vdev, MAX_NAME_SIZE);
253 prox_port_cfg[vdev_port_id].n_vlans = 1;
254 prox_port_cfg[vdev_port_id].vlan_tags[0] = 0;
257 prox_port_cfg[port_id].dpdk_mapping = vdev_port_id;
259 while ((i < PROX_MAX_VLAN_TAGS) && (prox_port_cfg[port_id].ip_addr[i].ip)) {
260 prox_port_cfg[vdev_port_id].ip_addr[i].ip = rte_be_to_cpu_32(prox_port_cfg[port_id].ip_addr[i].ip);
261 prox_port_cfg[vdev_port_id].ip_addr[i].prefix = prox_port_cfg[port_id].ip_addr[i].prefix;
264 prox_port_cfg[vdev_port_id].type = prox_port_cfg[port_id].type;
265 if (prox_port_cfg[vdev_port_id].type == PROX_PORT_MAC_HW) {
266 // If DPDK port MAC set to HW, then make sure the vdev has the same MAC as DPDK port
267 prox_port_cfg[vdev_port_id].type = PROX_PORT_MAC_SET;
268 rte_eth_macaddr_get(port_id, &prox_port_cfg[vdev_port_id].eth_addr);
269 plog_info("\tDPDK port %d MAC address pre-configured to MAC from port %d: "MAC_BYTES_FMT"\n",
270 vdev_port_id, port_id, MAC_BYTES(prox_port_cfg[vdev_port_id].eth_addr.addr_bytes));
272 memcpy(&prox_port_cfg[vdev_port_id].eth_addr, &prox_port_cfg[port_id].eth_addr, sizeof(prox_port_cfg[port_id].eth_addr));
274 if (prox_port_cfg[port_id].n_vlans == 0) {
275 prox_port_cfg[port_id].n_vlans = 1;
276 prox_port_cfg[port_id].vlan_tags[0] = 0;
279 nb_ports = prox_rte_eth_dev_count_avail();
280 /* get available ports configuration */
281 PROX_PANIC(use_dummy_devices && nb_ports, "Can't use dummy devices while there are also real ports\n");
283 if (use_dummy_devices) {
284 #if (RTE_VERSION >= RTE_VERSION_NUM(2,1,0,0))
285 nb_ports = prox_last_port_active() + 1;
286 plog_info("Creating %u dummy devices\n", nb_ports);
288 char port_name[32] = "0dummy_dev";
289 for (uint32_t i = 0; i < nb_ports; ++i) {
290 #if (RTE_VERSION > RTE_VERSION_NUM(17,5,0,1))
291 rte_vdev_init(port_name, "size=64,copy=0");
293 eth_dev_null_create(port_name, 0, PROX_RTE_ETHER_MIN_LEN, 0);
298 PROX_PANIC(use_dummy_devices, "Can't use dummy devices\n");
301 else if (prox_last_port_active() != -1) {
302 PROX_PANIC(nb_ports == 0, "\tError: DPDK could not find any port\n");
303 plog_info("\tDPDK has found %u ports\n", nb_ports);
306 if (nb_ports > PROX_MAX_PORTS) {
307 plog_warn("\tWarning: I can deal with at most %u ports."
308 " Please update PROX_MAX_PORTS and recompile.\n", PROX_MAX_PORTS);
310 nb_ports = PROX_MAX_PORTS;
313 #if (RTE_VERSION >= RTE_VERSION_NUM(17,5,0,0))
316 RTE_ETH_FOREACH_DEV(id) {
318 rte_eth_dev_get_name_by_port(id, name);
319 plog_info("\tFound DPDK port id %u %s\n", id, name);
320 if (id >= PROX_MAX_PORTS) {
321 plog_warn("\tWarning: I can deal with at most %u ports."
322 " Please update PROX_MAX_PORTS and recompile.\n", PROX_MAX_PORTS);
324 prox_port_cfg[id].available = 1;
325 if (id > port_id_max)
330 port_id_max = nb_ports - 1;
333 port_id_last = prox_last_port_active();
334 PROX_PANIC(port_id_last > port_id_max,
335 "\tError: invalid port(s) specified, last port index active: %d (max index is %d)\n",
336 port_id_last, port_id_max);
338 /* Assign ports to PROX interfaces & Read max RX/TX queues per port */
339 #if (RTE_VERSION >= RTE_VERSION_NUM(17,5,0,0))
340 for (uint8_t port_id = 0; port_id <= port_id_last; ++port_id) {
342 for (uint8_t port_id = 0; port_id <= nb_ports; ++port_id) {
344 /* skip ports that are not enabled */
345 if (!prox_port_cfg[port_id].active) {
347 #if (RTE_VERSION >= RTE_VERSION_NUM(17,5,0,0))
348 } else if (prox_port_cfg[port_id].available == 0) {
349 PROX_PANIC(1, "port %u enabled but not available\n", port_id);
352 plog_info("\tGetting info for rte dev %u\n", port_id);
353 rte_eth_dev_info_get(port_id, &dev_info);
354 struct prox_port_cfg* port_cfg = &prox_port_cfg[port_id];
355 port_cfg->socket = -1;
357 memcpy(&port_cfg->dev_info, &dev_info, sizeof(struct rte_eth_dev_info));
358 port_cfg->max_txq = dev_info.max_tx_queues;
359 port_cfg->max_rxq = dev_info.max_rx_queues;
360 port_cfg->max_rx_pkt_len = dev_info.max_rx_pktlen;
361 port_cfg->min_rx_bufsize = dev_info.min_rx_bufsize;
362 port_cfg->min_tx_desc = dev_info.tx_desc_lim.nb_min;
363 port_cfg->max_tx_desc = dev_info.tx_desc_lim.nb_max;
364 port_cfg->min_rx_desc = dev_info.rx_desc_lim.nb_min;
365 port_cfg->max_rx_desc = dev_info.rx_desc_lim.nb_max;
367 prox_strncpy(port_cfg->driver_name, dev_info.driver_name, sizeof(port_cfg->driver_name));
368 plog_info("\tPort %u : driver='%s' tx_queues=%d rx_queues=%d\n", port_id, !strcmp(port_cfg->driver_name, "")? "null" : port_cfg->driver_name, port_cfg->max_txq, port_cfg->max_rxq);
369 plog_info("\tPort %u : %d<=nb_tx_desc<=%d %d<=nb_rx_desc<=%d\n", port_id, port_cfg->min_tx_desc, port_cfg->max_tx_desc, port_cfg->min_rx_desc, port_cfg->max_rx_desc);
371 if (strncmp(port_cfg->driver_name, "rte_", 4) == 0) {
372 prox_strncpy(port_cfg->short_name, prox_port_cfg[port_id].driver_name + 4, sizeof(port_cfg->short_name));
373 } else if (strncmp(port_cfg->driver_name, "net_", 4) == 0) {
374 prox_strncpy(port_cfg->short_name, prox_port_cfg[port_id].driver_name + 4, sizeof(port_cfg->short_name));
376 prox_strncpy(port_cfg->short_name, prox_port_cfg[port_id].driver_name, sizeof(port_cfg->short_name));
379 if ((ptr = strstr(port_cfg->short_name, "_pmd")) != NULL) {
383 #if RTE_VERSION < RTE_VERSION_NUM(18,5,0,0)
384 pci_dev = dev_info.pci_dev;
386 if (!dev_info.device)
388 pci_dev = RTE_DEV_TO_PCI(dev_info.device);
393 snprintf(port_cfg->pci_addr, sizeof(port_cfg->pci_addr),
394 "%04x:%02x:%02x.%1x", pci_dev->addr.domain, pci_dev->addr.bus, pci_dev->addr.devid, pci_dev->addr.function);
395 /* Try to find the device's numa node */
397 snprintf(buf, sizeof(buf), "/sys/bus/pci/devices/%s/numa_node", port_cfg->pci_addr);
398 FILE* numa_node_fd = fopen(buf, "r");
400 if (fgets(buf, sizeof(buf), numa_node_fd) == NULL) {
401 plog_warn("Failed to read numa_node for device %s\n", port_cfg->pci_addr);
403 port_cfg->socket = strtol(buf, 0, 0);
404 if (port_cfg->socket == -1) {
405 plog_warn("System did not report numa_node for device %s\n", port_cfg->pci_addr);
407 fclose(numa_node_fd);
410 // In DPDK 18.08 vmxnet3 reports it supports IPV4 checksum, but packets does not go through when IPv4 cksum is enabled
411 if ((!strcmp(port_cfg->short_name, "vmxnet3")) && (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)) {
412 plog_info("\t\tDisabling IPV4 cksum on vmxnet3\n");
413 port_cfg->disabled_tx_offload |= DEV_TX_OFFLOAD_IPV4_CKSUM;
415 if ((!strcmp(port_cfg->short_name, "vmxnet3")) && (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM)) {
416 plog_info("\t\tDisabling UDP cksum on vmxnet3\n");
417 port_cfg->disabled_tx_offload |= DEV_TX_OFFLOAD_UDP_CKSUM;
419 // Some OVS versions reports that they support UDP offload and no IPv4 offload, but fails when UDP offload is enabled
420 if ((!strcmp(port_cfg->short_name, "virtio")) &&
421 ((port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM) == 0) &&
422 (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM)) {
423 plog_info("\t\tDisabling UDP cksum on virtio\n");
424 port_cfg->disabled_tx_offload |= DEV_TX_OFFLOAD_UDP_CKSUM;
429 /* Create rte ring-backed devices */
430 uint8_t init_rte_ring_dev(void)
432 uint8_t nb_ring_dev = 0;
434 for (uint8_t port_id = 0; port_id < PROX_MAX_PORTS; ++port_id) {
435 /* skip ports that are not enabled */
436 if (!prox_port_cfg[port_id].active) {
439 struct prox_port_cfg* port_cfg = &prox_port_cfg[port_id];
440 if (port_cfg->rx_ring[0] != '\0') {
441 plog_info("\tRing-backed port %u: rx='%s' tx='%s'\n", port_id, port_cfg->rx_ring, port_cfg->tx_ring);
443 struct rte_ring* rx_ring = rte_ring_lookup(port_cfg->rx_ring);
444 PROX_PANIC(rx_ring == NULL, "Ring %s not found for port %d!\n", port_cfg->rx_ring, port_id);
445 struct rte_ring* tx_ring = rte_ring_lookup(port_cfg->tx_ring);
446 PROX_PANIC(tx_ring == NULL, "Ring %s not found for port %d!\n", port_cfg->tx_ring, port_id);
448 int ret = rte_eth_from_rings(port_cfg->names[0], &rx_ring, 1, &tx_ring, 1, rte_socket_id());
449 PROX_PANIC(ret != 0, "Failed to create eth_dev from rings for port %d\n", port_id);
451 port_cfg->port_conf.intr_conf.lsc = 0; /* Link state interrupt not supported for ring-backed ports */
460 static void print_port_capa(struct prox_port_cfg *port_cfg)
464 port_id = port_cfg - prox_port_cfg;
465 plog_info("\t*** Initializing port %u ***\n", port_id);
466 plog_info("\t\tPort name is set to %s\n", port_cfg->names[0]);
467 plog_info("\t\tPort max RX/TX queue is %u/%u\n", port_cfg->max_rxq, port_cfg->max_txq);
468 plog_info("\t\tPort driver is %s\n", port_cfg->driver_name);
469 #if RTE_VERSION >= RTE_VERSION_NUM(16,4,0,0)
470 plog_info("\t\tSupported speed mask = 0x%x\n", port_cfg->dev_info.speed_capa);
472 if (port_cfg->max_link_speed != UINT32_MAX) {
473 plog_info("\t\tHighest link speed capa = %d Mbps\n", port_cfg->max_link_speed);
476 #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1)
477 plog_info("\t\tRX offload capa = 0x%lx = ", port_cfg->dev_info.rx_offload_capa);
478 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_VLAN_STRIP)
479 plog_info("VLAN STRIP | ");
480 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_IPV4_CKSUM)
481 plog_info("IPV4 CKSUM | ");
482 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_UDP_CKSUM)
483 plog_info("UDP CKSUM | ");
484 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_CKSUM)
485 plog_info("TCP CKSUM | ");
486 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TCP_LRO)
487 plog_info("TCP LRO | ");
488 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_QINQ_STRIP)
489 plog_info("QINQ STRIP | ");
490 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_OUTER_IPV4_CKSUM)
491 plog_info("OUTER_IPV4_CKSUM | ");
492 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_MACSEC_STRIP)
493 plog_info("MACSEC STRIP | ");
494 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_HEADER_SPLIT)
495 plog_info("HEADER SPLIT | ");
496 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_VLAN_FILTER)
497 plog_info("VLAN FILTER | ");
498 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_VLAN_EXTEND)
499 plog_info("VLAN EXTEND | ");
500 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_JUMBO_FRAME)
501 plog_info("JUMBO FRAME | ");
502 #if defined(DEV_RX_OFFLOAD_CRC_STRIP)
503 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_CRC_STRIP)
504 plog_info("CRC STRIP | ");
506 #if defined(DEV_RX_OFFLOAD_KEEP_CRC)
507 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_KEEP_CRC)
508 plog_info("KEEP CRC | ");
510 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_SCATTER)
511 plog_info("SCATTER | ");
512 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_TIMESTAMP)
513 plog_info("TIMESTAMP | ");
514 if (port_cfg->dev_info.rx_offload_capa & DEV_RX_OFFLOAD_SECURITY)
515 plog_info("SECURITY ");
518 plog_info("\t\tTX offload capa = 0x%lx = ", port_cfg->dev_info.tx_offload_capa);
519 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VLAN_INSERT)
520 plog_info("VLAN INSERT | ");
521 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPV4_CKSUM)
522 plog_info("IPV4 CKSUM | ");
523 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_CKSUM)
524 plog_info("UDP CKSUM | ");
525 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_CKSUM)
526 plog_info("TCP CKSUM | ");
527 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SCTP_CKSUM)
528 plog_info("SCTP CKSUM | ");
529 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_TCP_TSO)
530 plog_info("TCP TS0 | ");
531 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_TSO)
532 plog_info("UDP TSO | ");
533 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM)
534 plog_info("OUTER IPV4 CKSUM | ");
535 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_QINQ_INSERT)
536 plog_info("QINQ INSERT | ");
537 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_VXLAN_TNL_TSO)
538 plog_info("VLAN TNL TSO | ");
539 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GRE_TNL_TSO)
540 plog_info("GRE TNL TSO | ");
541 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IPIP_TNL_TSO)
542 plog_info("IPIP TNL TSO | ");
543 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_GENEVE_TNL_TSO)
544 plog_info("GENEVE TNL TSO | ");
545 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MACSEC_INSERT)
546 plog_info("MACSEC INSERT | ");
547 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MT_LOCKFREE)
548 plog_info("MT LOCKFREE | ");
549 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_MULTI_SEGS)
550 plog_info("MULTI SEG | ");
551 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_SECURITY)
552 plog_info("SECURITY | ");
553 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_UDP_TNL_TSO)
554 plog_info("UDP TNL TSO | ");
555 if (port_cfg->dev_info.tx_offload_capa & DEV_TX_OFFLOAD_IP_TNL_TSO)
556 plog_info("IP TNL TSO | ");
559 plog_info("\t\trx_queue_offload_capa = 0x%lx\n", port_cfg->dev_info.rx_queue_offload_capa);
560 plog_info("\t\ttx_queue_offload_capa = 0x%lx\n", port_cfg->dev_info.tx_queue_offload_capa);
561 plog_info("\t\tflow_type_rss_offloads = 0x%lx\n", port_cfg->dev_info.flow_type_rss_offloads);
562 plog_info("\t\tdefault RX port conf: burst_size = %d, ring_size = %d, nb_queues = %d\n", port_cfg->dev_info.default_rxportconf.burst_size, port_cfg->dev_info.default_rxportconf.ring_size, port_cfg->dev_info.default_rxportconf.nb_queues);
563 plog_info("\t\tdefault TX port conf: burst_size = %d, ring_size = %d, nb_queues = %d\n", port_cfg->dev_info.default_txportconf.burst_size, port_cfg->dev_info.default_txportconf.ring_size, port_cfg->dev_info.default_txportconf.nb_queues);
567 static void get_max_link_speed(struct prox_port_cfg *port_cfg)
569 port_cfg->max_link_speed = UINT32_MAX;
571 #if RTE_VERSION >= RTE_VERSION_NUM(16,4,0,0)
572 // virtio and vmxnet3 reports fake max_link_speed
573 if (strcmp(port_cfg->short_name, "vmxnet3") && strcmp(port_cfg->short_name, "virtio")) {
574 // Get link_speed from highest capability from the port
575 // This will be used by gen and lat for extrapolation purposes
576 // The negotiated link_speed (as reported by rte_eth_link_get
577 // or rte_eth_link_get_nowait) might be reported too late
578 // and might result in wrong exrapolation, and hence should not be used
579 // for extrapolation purposes
580 if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_100G)
581 port_cfg->max_link_speed = ETH_SPEED_NUM_100G;
582 else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_56G)
583 port_cfg->max_link_speed = ETH_SPEED_NUM_56G;
584 else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_50G)
585 port_cfg->max_link_speed = ETH_SPEED_NUM_50G;
586 else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_40G)
587 port_cfg->max_link_speed = ETH_SPEED_NUM_40G;
588 else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_25G)
589 port_cfg->max_link_speed = ETH_SPEED_NUM_25G;
590 else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_20G)
591 port_cfg->max_link_speed = ETH_SPEED_NUM_20G;
592 else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_10G)
593 port_cfg->max_link_speed = ETH_SPEED_NUM_10G;
594 else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_5G)
595 port_cfg->max_link_speed = ETH_SPEED_NUM_5G;
596 else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_2_5G)
597 port_cfg->max_link_speed = ETH_SPEED_NUM_2_5G;
598 else if (port_cfg->dev_info.speed_capa & ETH_LINK_SPEED_1G)
599 port_cfg->max_link_speed = ETH_SPEED_NUM_1G;
600 else if (port_cfg->dev_info.speed_capa & (ETH_LINK_SPEED_100M_HD | ETH_LINK_SPEED_100M))
601 port_cfg->max_link_speed = ETH_SPEED_NUM_100M;
602 else if (port_cfg->dev_info.speed_capa & (ETH_LINK_SPEED_10M_HD | ETH_LINK_SPEED_10M))
603 port_cfg->max_link_speed = ETH_SPEED_NUM_10M;
609 static void init_port(struct prox_port_cfg *port_cfg)
611 static char dummy_pool_name[] = "0_dummy";
612 struct rte_eth_link link;
616 get_max_link_speed(port_cfg);
617 print_port_capa(port_cfg);
618 port_id = port_cfg - prox_port_cfg;
619 PROX_PANIC(port_cfg->n_rxq == 0 && port_cfg->n_txq == 0,
620 "\t\t port %u is enabled but no RX or TX queues have been configured", port_id);
622 if (port_cfg->n_rxq == 0) {
623 /* not receiving on this port */
624 plog_info("\t\tPort %u had no RX queues, setting to 1\n", port_id);
626 uint32_t mbuf_size = TX_MBUF_SIZE;
627 if (mbuf_size < port_cfg->min_rx_bufsize + RTE_PKTMBUF_HEADROOM + sizeof(struct rte_mbuf))
628 mbuf_size = port_cfg->min_rx_bufsize + RTE_PKTMBUF_HEADROOM + sizeof(struct rte_mbuf);
630 plog_info("\t\tAllocating dummy memory pool on socket %u with %u elements of size %u\n",
631 port_cfg->socket, port_cfg->n_rxd, mbuf_size);
632 port_cfg->pool[0] = rte_mempool_create(dummy_pool_name, port_cfg->n_rxd, mbuf_size,
634 sizeof(struct rte_pktmbuf_pool_private),
635 rte_pktmbuf_pool_init, NULL,
636 prox_pktmbuf_init, 0,
637 port_cfg->socket, 0);
638 PROX_PANIC(port_cfg->pool[0] == NULL, "Failed to allocate dummy memory pool on socket %u with %u elements\n",
639 port_cfg->socket, port_cfg->n_rxd);
640 dummy_pool_name[0]++;
642 // Most pmd should now support setting mtu
643 if (port_cfg->mtu + PROX_RTE_ETHER_HDR_LEN + PROX_RTE_ETHER_CRC_LEN > port_cfg->max_rx_pkt_len) {
644 plog_info("\t\tMTU is too big for the port, reducing MTU from %d to %d\n", port_cfg->mtu, port_cfg->max_rx_pkt_len);
645 port_cfg->mtu = port_cfg->max_rx_pkt_len;
647 plog_info("\t\tSetting MTU size to %u for port %u ...\n", port_cfg->mtu, port_id);
648 ret = rte_eth_dev_set_mtu(port_id, port_cfg->mtu);
650 plog_err("\t\t\trte_eth_dev_set_mtu() failed on port %u: error %d\n", port_id, ret);
652 if (port_cfg->n_txq == 0) {
653 /* not sending on this port */
654 plog_info("\t\tPort %u had no TX queues, setting to 1\n", port_id);
659 if (port_cfg->n_rxq > 1) {
660 // Enable RSS if multiple receive queues
661 if (strcmp(port_cfg->short_name, "virtio")) {
662 port_cfg->port_conf.rxmode.mq_mode |= ETH_MQ_RX_RSS;
663 port_cfg->port_conf.rx_adv_conf.rss_conf.rss_key = toeplitz_init_key;
664 port_cfg->port_conf.rx_adv_conf.rss_conf.rss_key_len = TOEPLITZ_KEY_LEN;
665 #if RTE_VERSION >= RTE_VERSION_NUM(2,0,0,0)
666 port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IP|ETH_RSS_UDP;
668 port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf = ETH_RSS_IPV4|ETH_RSS_NONF_IPV4_UDP;
673 // Make sure that the requested RSS offload is supported by the PMD
674 #if RTE_VERSION >= RTE_VERSION_NUM(2,0,0,0)
675 port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf &= port_cfg->dev_info.flow_type_rss_offloads;
677 if (strcmp(port_cfg->short_name, "virtio")) {
678 plog_info("\t\t Enabling RSS rss_hf = 0x%lx (requested 0x%llx, supported 0x%lx)\n", port_cfg->port_conf.rx_adv_conf.rss_conf.rss_hf, ETH_RSS_IP|ETH_RSS_UDP, port_cfg->dev_info.flow_type_rss_offloads);
680 plog_info("\t\t Not enabling RSS on virtio port");
683 // rxmode such as hw src strip
684 #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1)
685 #if defined (DEV_RX_OFFLOAD_CRC_STRIP)
686 CONFIGURE_RX_OFFLOAD(DEV_RX_OFFLOAD_CRC_STRIP);
688 #if defined (DEV_RX_OFFLOAD_KEEP_CRC)
689 CONFIGURE_RX_OFFLOAD(DEV_RX_OFFLOAD_KEEP_CRC);
691 CONFIGURE_RX_OFFLOAD(DEV_RX_OFFLOAD_JUMBO_FRAME);
692 CONFIGURE_RX_OFFLOAD(DEV_RX_OFFLOAD_VLAN_STRIP);
694 if (port_cfg->requested_rx_offload & DEV_RX_OFFLOAD_CRC_STRIP) {
695 port_cfg->port_conf.rxmode.hw_strip_crc = 1;
697 if (port_cfg->requested_rx_offload & DEV_RX_OFFLOAD_JUMBO_FRAME) {
698 port_cfg->port_conf.rxmode.jumbo_frame = 1;
702 // IPV4, UDP, SCTP Checksums
703 #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1)
704 CONFIGURE_TX_OFFLOAD(DEV_TX_OFFLOAD_IPV4_CKSUM);
705 CONFIGURE_TX_OFFLOAD(DEV_TX_OFFLOAD_UDP_CKSUM);
706 CONFIGURE_TX_OFFLOAD(DEV_TX_OFFLOAD_VLAN_INSERT);
708 if ((port_cfg->dev_info.tx_offload_capa & (DEV_TX_OFFLOAD_IPV4_CKSUM | DEV_TX_OFFLOAD_UDP_CKSUM)) == 0) {
709 port_cfg->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOOFFLOADS;
710 plog_info("\t\tDisabling TX offloads as pmd reports that it does not support them)\n");
712 if (!strcmp(port_cfg->short_name, "vmxnet3")) {
713 port_cfg->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOXSUMSCTP;
714 plog_info("\t\tDisabling SCTP offload on port %d as vmxnet3 does not support them\n", port_id);
718 #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1)
719 CONFIGURE_TX_OFFLOAD(DEV_TX_OFFLOAD_MULTI_SEGS);
721 if (!strcmp(port_cfg->short_name, "vmxnet3")) {
722 port_cfg->tx_conf.txq_flags |= ETH_TXQ_FLAGS_NOMULTSEGS;
723 plog_info("\t\tDisabling TX multsegs on port %d as vmxnet3 does not support them\n", port_id);
724 } else if (port_cfg->tx_conf.txq_flags & ETH_TXQ_FLAGS_NOMULTSEGS)
725 plog_info("\t\tDisabling TX multsegs on port %d\n", port_id);
727 plog_info("\t\tEnabling TX multsegs on port %d\n", port_id);
729 if (port_cfg->tx_conf.txq_flags & ETH_TXQ_FLAGS_NOOFFLOADS)
730 plog_info("\t\tEnabling No TX offloads on port %d\n", port_id);
732 plog_info("\t\tTX offloads enabled on port %d\n", port_id);
736 #if RTE_VERSION >= RTE_VERSION_NUM(18,8,0,1)
737 CONFIGURE_TX_OFFLOAD(DEV_TX_OFFLOAD_MBUF_FAST_FREE);
739 if (port_cfg->tx_conf.txq_flags & ETH_TXQ_FLAGS_NOREFCOUNT)
740 plog_info("\t\tEnabling No refcnt on port %d\n", port_id);
742 plog_info("\t\tRefcnt enabled on port %d\n", port_id);
745 plog_info("\t\tConfiguring port %u... with %u RX queues and %u TX queues\n",
746 port_id, port_cfg->n_rxq, port_cfg->n_txq);
748 PROX_PANIC(port_cfg->n_rxq > port_cfg->max_rxq, "\t\t\tToo many RX queues (configuring %u, max is %u)\n", port_cfg->n_rxq, port_cfg->max_rxq);
749 PROX_PANIC(port_cfg->n_txq > port_cfg->max_txq, "\t\t\tToo many TX queues (configuring %u, max is %u)\n", port_cfg->n_txq, port_cfg->max_txq);
751 if (!strcmp(port_cfg->short_name, "ixgbe_vf") ||
752 !strcmp(port_cfg->short_name, "virtio") ||
753 #if RTE_VERSION < RTE_VERSION_NUM(1,8,0,0)
754 !strcmp(port_cfg->short_name, "i40e") ||
756 !strcmp(port_cfg->short_name, "i40e_vf") ||
757 !strcmp(port_cfg->short_name, "avp") || /* Wind River */
758 !strcmp(port_cfg->driver_name, "") || /* NULL device */
759 !strcmp(port_cfg->short_name, "vmxnet3")) {
760 port_cfg->port_conf.intr_conf.lsc = 0;
761 plog_info("\t\tDisabling link state interrupt for vmxnet3/VF/virtio (unsupported)\n");
764 if (port_cfg->lsc_set_explicitely) {
765 port_cfg->port_conf.intr_conf.lsc = port_cfg->lsc_val;
766 plog_info("\t\tOverriding link state interrupt configuration to '%s'\n", port_cfg->lsc_val? "enabled" : "disabled");
768 if (port_cfg->n_txd < port_cfg->min_tx_desc) {
769 plog_info("\t\tNumber of TX descriptors is set to %d (minimum required for %s\n", port_cfg->min_tx_desc, port_cfg->short_name);
770 port_cfg->n_txd = port_cfg->min_tx_desc;
773 if (port_cfg->n_rxd < port_cfg->min_rx_desc) {
774 plog_info("\t\tNumber of RX descriptors is set to %d (minimum required for %s\n", port_cfg->min_rx_desc, port_cfg->short_name);
775 port_cfg->n_rxd = port_cfg->min_rx_desc;
778 if (port_cfg->n_txd > port_cfg->max_tx_desc) {
779 plog_info("\t\tNumber of TX descriptors is set to %d (maximum required for %s\n", port_cfg->max_tx_desc, port_cfg->short_name);
780 port_cfg->n_txd = port_cfg->max_tx_desc;
783 if (port_cfg->n_rxd > port_cfg->max_rx_desc) {
784 plog_info("\t\tNumber of RX descriptors is set to %d (maximum required for %s\n", port_cfg->max_rx_desc, port_cfg->short_name);
785 port_cfg->n_rxd = port_cfg->max_rx_desc;
788 ret = rte_eth_dev_configure(port_id, port_cfg->n_rxq,
789 port_cfg->n_txq, &port_cfg->port_conf);
790 PROX_PANIC(ret < 0, "\t\t\trte_eth_dev_configure() failed on port %u: %s (%d)\n", port_id, strerror(-ret), ret);
792 if (port_cfg->port_conf.intr_conf.lsc) {
793 rte_eth_dev_callback_register(port_id, RTE_ETH_EVENT_INTR_LSC, lsc_cb, NULL);
796 plog_info("\t\tMAC address set to "MAC_BYTES_FMT"\n", MAC_BYTES(port_cfg->eth_addr.addr_bytes));
798 /* initialize TX queues first */
799 for (uint16_t queue_id = 0; queue_id < port_cfg->n_txq; ++queue_id) {
800 plog_info("\t\tSetting up TX queue %u on socket %u with %u desc\n",
801 queue_id, port_cfg->socket, port_cfg->n_txd);
802 ret = rte_eth_tx_queue_setup(port_id, queue_id, port_cfg->n_txd,
803 port_cfg->socket, &port_cfg->tx_conf);
804 PROX_PANIC(ret < 0, "\t\t\trte_eth_tx_queue_setup() failed on port %u: error %d\n", port_id, ret);
807 /* initialize RX queues */
808 for (uint16_t queue_id = 0; queue_id < port_cfg->n_rxq; ++queue_id) {
809 plog_info("\t\tSetting up RX queue %u on port %u on socket %u with %u desc (pool 0x%p)\n",
810 queue_id, port_id, port_cfg->socket,
811 port_cfg->n_rxd, port_cfg->pool[queue_id]);
812 ret = rte_eth_rx_queue_setup(port_id, queue_id,
814 port_cfg->socket, &port_cfg->rx_conf,
815 port_cfg->pool[queue_id]);
816 PROX_PANIC(ret < 0, "\t\t\trte_eth_rx_queue_setup() failed on port %u: error %s (%d)\n", port_id, strerror(-ret), ret);
819 plog_info("\t\tStarting up port %u ...", port_id);
820 ret = rte_eth_dev_start(port_id);
822 PROX_PANIC(ret < 0, "\n\t\t\trte_eth_dev_start() failed on port %u: error %d\n", port_id, ret);
823 plog_info(" done: ");
825 if (prox_port_cfg[port_id].is_vdev) {
826 for (int vlan_id = 0; vlan_id < prox_port_cfg[port_id].n_vlans; vlan_id++) {
827 set_ip_address(prox_port_cfg[port_id].names[vlan_id], &prox_port_cfg[port_id].ip_addr[vlan_id].ip, prox_port_cfg[port_id].ip_addr[vlan_id].prefix);
830 /* Getting link status can be done without waiting if Link
831 State Interrupt is enabled since in that case, if the link
832 is recognized as being down, an interrupt will notify that
834 if (port_cfg->port_conf.intr_conf.lsc)
835 rte_eth_link_get_nowait(port_id, &link);
837 rte_eth_link_get(port_id, &link);
839 port_cfg->link_up = link.link_status;
840 port_cfg->link_speed = link.link_speed;
842 if (link.link_status) {
843 plog_info("Link Up - speed %'u Mbps - %s\n",
845 (link.link_duplex == ETH_LINK_FULL_DUPLEX) ?
846 "full-duplex" : "half-duplex");
849 plog_info("Link Down\n");
852 if (port_cfg->promiscuous) {
853 rte_eth_promiscuous_enable(port_id);
854 plog_info("\t\tport %u in promiscuous mode\n", port_id);
857 if (strcmp(port_cfg->short_name, "ixgbe_vf") &&
858 strcmp(port_cfg->short_name, "i40e") &&
859 strcmp(port_cfg->short_name, "i40e_vf") &&
860 strcmp(port_cfg->short_name, "vmxnet3")) {
861 for (uint8_t i = 0; i < port_cfg->n_rxq; ++i) {
862 ret = rte_eth_dev_set_rx_queue_stats_mapping(port_id, i, i);
864 plog_info("\t\trte_eth_dev_set_rx_queue_stats_mapping() failed: error %d\n", ret);
867 for (uint8_t i = 0; i < port_cfg->n_txq; ++i) {
868 ret = rte_eth_dev_set_tx_queue_stats_mapping(port_id, i, i);
870 plog_info("\t\trte_eth_dev_set_tx_queue_stats_mapping() failed: error %d\n", ret);
874 if (port_cfg->nb_mc_addr) {
875 rte_eth_allmulticast_enable(port_id);
876 if ((ret = rte_eth_dev_set_mc_addr_list(port_id, port_cfg->mc_addr, port_cfg->nb_mc_addr)) != 0) {
877 plog_err("\t\trte_eth_dev_set_mc_addr_list returns %d on port %u\n", ret, port_id);
878 port_cfg->nb_mc_addr = 0;
879 rte_eth_allmulticast_disable(port_id);
880 plog_info("\t\tport %u NOT in multicast mode as failed to add mcast address\n", port_id);
882 plog_info("\t\trte_eth_dev_set_mc_addr_list(%d addr) on port %u\n", port_cfg->nb_mc_addr, port_id);
883 plog_info("\t\tport %u in multicast mode\n", port_id);
888 void init_port_all(void)
890 enum rte_proc_type_t proc_type;
891 proc_type = rte_eal_process_type();
892 if (proc_type == RTE_PROC_SECONDARY) {
893 plog_info("\tSkipping port initialization as secondary process\n");
896 uint8_t max_port_idx = prox_last_port_active() + 1;
898 for (uint8_t portid = 0; portid < max_port_idx; ++portid) {
899 if (!prox_port_cfg[portid].active) {
902 init_port(&prox_port_cfg[portid]);
906 void close_ports_atexit(void)
908 uint8_t max_port_idx = prox_last_port_active() + 1;
910 for (uint8_t portid = 0; portid < max_port_idx; ++portid) {
911 if (!prox_port_cfg[portid].active) {
914 plog_info("Closing port %u\n", portid);
915 rte_eth_dev_close(portid);
918 if (lcore_cfg == NULL)
921 struct lcore_cfg *lconf = NULL;
922 struct task_args *targ;
923 while (core_targ_next(&lconf, &targ, 0) == 0) {
925 rte_mempool_free(targ->pool);
926 plog_info("freeing pool %p\n", targ->pool);
932 void init_port_addr(void)
934 struct prox_port_cfg *port_cfg;
935 enum rte_proc_type_t proc_type;
938 for (uint8_t port_id = 0; port_id < PROX_MAX_PORTS; ++port_id) {
939 if (!prox_port_cfg[port_id].active) {
942 port_cfg = &prox_port_cfg[port_id];
944 switch (port_cfg->type) {
945 case PROX_PORT_MAC_HW:
946 rte_eth_macaddr_get(port_id, &port_cfg->eth_addr);
948 case PROX_PORT_MAC_RAND:
949 prox_rte_eth_random_addr(port_cfg->eth_addr.addr_bytes);
951 case PROX_PORT_MAC_SET:
952 proc_type = rte_eal_process_type();
953 if (proc_type == RTE_PROC_SECONDARY) {
954 plog_warn("\tport %u: unable to change port mac address as secondary process\n", port_id);
955 } else if ((rc = rte_eth_dev_default_mac_addr_set(port_id, &port_cfg->eth_addr)) != 0)
956 plog_warn("\tport %u: failed to set mac address. Error = %d\n", port_id, rc);
958 plog_info("Setting MAC to "MAC_BYTES_FMT"\n", MAC_BYTES(port_cfg->eth_addr.addr_bytes));
964 int port_is_active(uint8_t port_id)
966 if (port_id > PROX_MAX_PORTS) {
967 plog_info("requested port is higher than highest supported port ID (%u)\n", PROX_MAX_PORTS);
971 struct prox_port_cfg* port_cfg = &prox_port_cfg[port_id];
972 if (!port_cfg->active) {
973 plog_info("Port %u is not active\n", port_id);