Skip to content

Commit

Permalink
net/bonding: fix PCI address comparison on non-PCI ports
Browse files Browse the repository at this point in the history
[ upstream commit 3b37cc0 ]

The bonding PMD will iterate over all available ETH ports and for each,
compare a chunk of bytes at an offset that would correspond to the PCI
address in an rte_pci_device.

This is incorrect and unsafe. Also, the rte_device using this PCI
address is already found, no need to compare again the PCI address of
all eth devices.

Refactoring the code to fix this, the initial check to find the PCI bus
is out of scope.

Fixes: c848b51 ("net/bonding: support bifurcated driver in eal")

Signed-off-by: Gaetan Rivet <grive@u256.net>
Acked-by: Min Hu (Connor) <humin29@huawei.com>
  • Loading branch information
Gaetan Rivet authored and bluca committed Feb 2, 2021
1 parent 68a10f5 commit a58c0cc
Showing 1 changed file with 25 additions and 33 deletions.
58 changes: 25 additions & 33 deletions drivers/net/bonding/rte_eth_bond_args.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,37 @@ const char *pmd_bond_init_valid_arguments[] = {
NULL
};

static inline int
bond_pci_addr_cmp(const struct rte_device *dev, const void *_pci_addr)
{
const struct rte_pci_device *pdev = RTE_DEV_TO_PCI_CONST(dev);
const struct rte_pci_addr *paddr = _pci_addr;

return rte_pci_addr_cmp(&pdev->addr, paddr);
}

static inline int
find_port_id_by_pci_addr(const struct rte_pci_addr *pci_addr)
{
struct rte_pci_device *pci_dev;
struct rte_pci_addr *eth_pci_addr;
struct rte_bus *pci_bus;
struct rte_device *dev;
unsigned i;

RTE_ETH_FOREACH_DEV(i) {
pci_dev = RTE_ETH_DEV_TO_PCI(&rte_eth_devices[i]);
eth_pci_addr = &pci_dev->addr;
pci_bus = rte_bus_find_by_name("pci");
if (pci_bus == NULL) {
RTE_BOND_LOG(ERR, "No PCI bus found");
return -1;
}

if (pci_addr->bus == eth_pci_addr->bus &&
pci_addr->devid == eth_pci_addr->devid &&
pci_addr->domain == eth_pci_addr->domain &&
pci_addr->function == eth_pci_addr->function)
return i;
dev = pci_bus->find_device(NULL, bond_pci_addr_cmp, pci_addr);
if (dev == NULL) {
RTE_BOND_LOG(ERR, "unable to find PCI device");
return -1;
}

RTE_ETH_FOREACH_DEV(i)
if (rte_eth_devices[i].device == dev)
return i;
return -1;
}

Expand All @@ -57,15 +71,6 @@ find_port_id_by_dev_name(const char *name)
return -1;
}

static inline int
bond_pci_addr_cmp(const struct rte_device *dev, const void *_pci_addr)
{
const struct rte_pci_device *pdev = RTE_DEV_TO_PCI_CONST(dev);
const struct rte_pci_addr *paddr = _pci_addr;

return rte_pci_addr_cmp(&pdev->addr, paddr);
}

/**
* Parses a port identifier string to a port id by pci address, then by name,
* and finally port id.
Expand All @@ -74,23 +79,10 @@ static inline int
parse_port_id(const char *port_str)
{
struct rte_pci_addr dev_addr;
struct rte_bus *pci_bus;
struct rte_device *dev;
int port_id;

pci_bus = rte_bus_find_by_name("pci");
if (pci_bus == NULL) {
RTE_BOND_LOG(ERR, "unable to find PCI bus\n");
return -1;
}

/* try parsing as pci address, physical devices */
if (pci_bus->parse(port_str, &dev_addr) == 0) {
dev = pci_bus->find_device(NULL, bond_pci_addr_cmp, &dev_addr);
if (dev == NULL) {
RTE_BOND_LOG(ERR, "unable to find PCI device");
return -1;
}
if (rte_pci_addr_parse(port_str, &dev_addr) == 0) {
port_id = find_port_id_by_pci_addr(&dev_addr);
if (port_id < 0)
return -1;
Expand Down

0 comments on commit a58c0cc

Please sign in to comment.