suricata
util-dpdk-bonding.c
Go to the documentation of this file.
1/* Copyright (C) 2023 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Lukas Sismis <lukas.sismis@gmail.com>
22 */
23
24#include "suricata-common.h"
25#include "util-dpdk-bonding.h"
26
27#ifdef HAVE_DPDK
28
29#include "util-dpdk.h"
30#include "util-debug.h"
31
32/**
33 * Determines if the port is Bond or not by evaluating device driver name
34 * @param pid port ID
35 * @return 0 - the device si Bond PMD, 1 - regular device, <0 error
36 */
37int32_t BondingIsBond(uint16_t pid)
38{
39 struct rte_eth_dev_info di;
40 int32_t ret = rte_eth_dev_info_get(pid, &di);
41 if (ret < 0) {
42 SCLogError("%s: unable to get device info (err: %s)", DPDKGetPortNameByPortID(pid),
43 rte_strerror(-ret));
44 return ret;
45 }
46
47 return strcmp(di.driver_name, "net_bonding") == 0 ? 0 : 1;
48}
49
50uint16_t BondingMemberDevicesGet(
51 uint16_t bond_pid, uint16_t bonded_devs[], uint16_t bonded_devs_length)
52{
53#ifdef HAVE_DPDK_BOND
54#if RTE_VERSION >= RTE_VERSION_NUM(23, 11, 0, 0)
55 int32_t len = rte_eth_bond_members_get(bond_pid, bonded_devs, bonded_devs_length);
56#else
57 int32_t len = rte_eth_bond_slaves_get(bond_pid, bonded_devs, bonded_devs_length);
58#endif /* RTE_VERSION >= RTE_VERSION_NUM(23, 11, 0, 0) */
59
60 if (len == 0)
61 FatalError("%s: no bonded devices found", DPDKGetPortNameByPortID(bond_pid));
62 else if (len < 0)
63 FatalError("%s: unable to get bonded devices (err: %s)", DPDKGetPortNameByPortID(bond_pid),
64 rte_strerror(-len));
65
66 return len;
67#else
69 "%s: bond port not supported in DPDK installation", DPDKGetPortNameByPortID(bond_pid));
70#endif
71}
72
73int32_t BondingAllDevicesSameDriver(uint16_t bond_pid)
74{
75 uint16_t bonded_devs[RTE_MAX_ETHPORTS] = { 0 };
76 uint16_t len = BondingMemberDevicesGet(bond_pid, bonded_devs, RTE_MAX_ETHPORTS);
77
78 const char *driver_name = NULL, *first_driver_name = NULL;
79 struct rte_eth_dev_info di = { 0 };
80
81 for (uint16_t i = 0; i < len; i++) {
82 int32_t ret = rte_eth_dev_info_get(bonded_devs[i], &di);
83 if (ret < 0)
84 FatalError("%s: unable to get device info (err: %s)",
85 DPDKGetPortNameByPortID(bonded_devs[i]), rte_strerror(-ret));
86
87 if (i == 0) {
88 first_driver_name = di.driver_name;
89 } else {
90 driver_name = di.driver_name;
91 if (strncmp(first_driver_name, driver_name,
92 MIN(strlen(first_driver_name), strlen(driver_name))) != 0) {
93 return -EINVAL; // inconsistent drivers
94 }
95 }
96 }
97
98 return 0;
99}
100
101/**
102 * Translates to the driver that is actually used by the bonded ports
103 * \param bond_pid
104 * \return driver name, FatalError otherwise
105 */
106const char *BondingDeviceDriverGet(uint16_t bond_pid)
107{
108 uint16_t bonded_devs[RTE_MAX_ETHPORTS] = { 0 };
109 BondingMemberDevicesGet(bond_pid, bonded_devs, RTE_MAX_ETHPORTS);
110
111 struct rte_eth_dev_info di = { 0 };
112 int32_t ret = rte_eth_dev_info_get(bonded_devs[0], &di);
113 if (ret < 0)
114 FatalError("%s: unable to get device info (err: %s)",
115 DPDKGetPortNameByPortID(bonded_devs[0]), rte_strerror(-ret));
116
117 return di.driver_name;
118}
119
120#endif /* HAVE_DPDK */
uint8_t len
#define MIN(x, y)
#define FatalError(...)
Definition util-debug.h:510
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267