On Fri, Apr 17, 2026 at 09:51:36AM -0700, Stephen Hemminger wrote:
> The bonding PMD's secondary process attach path registered the
> ethdev but never installed rx_pkt_burst or tx_pkt_burst, leaving
> both as NULL. Any rx_burst or tx_burst call from a secondary
> process therefore crashed with a NULL pointer dereference.
>
> Fully sharing bonding state across processes would be
> overly complex. Instead, install blackhole burst functions
> in the secondary so the data path is safe by default. Rx returns 0
> and Tx frees the mbufs and reports them as transmitted,
> matching /dev/null semantics so applications do not spin
> retrying. Each stub logs once at NOTICE level on first use.
>
> Also reject bond mode changes from a secondary process.
> rte_eth_bond_mode_set() is callable from secondary, and
> without this guard it would overwrite the secondary's safe
> burst stubs with real per-mode functions whose internal
> state is not valid outside the primary, reintroducing the
> crash by another path.
>
> This keeps secondary support available for the more
> common use cases of procinfo and packet capture.
>
> Bugzilla ID: 1698
> Fixes: 4852aa8f6e21 ("drivers/net: enable hotplug on secondary process")
> Cc: [email protected]
>
> Signed-off-by: Stephen Hemminger <[email protected]>
> ---
Acked-by: Bruce Richardson <[email protected]>
However, see comment below.
> drivers/net/bonding/rte_eth_bond_pmd.c | 43 +++++++++++++++++++++++++-
> 1 file changed, 42 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/bonding/rte_eth_bond_pmd.c
> b/drivers/net/bonding/rte_eth_bond_pmd.c
> index 96725071da..6a42257d2b 100644
> --- a/drivers/net/bonding/rte_eth_bond_pmd.c
> +++ b/drivers/net/bonding/rte_eth_bond_pmd.c
> @@ -56,6 +56,33 @@ get_vlan_offset(struct rte_ether_hdr *eth_hdr, uint16_t
> *proto)
> return vlan_offset;
> }
>
> +static uint16_t
> +bond_ethdev_rx_secondary(void *queue __rte_unused,
> + struct rte_mbuf **bufs __rte_unused, uint16_t nb_pkts
> __rte_unused)
> +{
> + static bool once = true;
> +
> + if (once) {
> + /* once per process is enough of a notice */
> + RTE_BOND_LOG(NOTICE, "receive not supported in secondary");
Since this does nothing, I think that an ERROR level warning is more
appropriate than notice. If not for Rx, certainly for Tx which just
silently drops packets!
> + once = false;
> + }
> + return 0;
> +}
> +
> +static uint16_t
> +bond_ethdev_tx_secondary(void *queue __rte_unused, struct rte_mbuf **bufs,
> uint16_t nb_pkts)
> +{
> + static bool once = true;
> +
> + if (once) {
> + RTE_BOND_LOG(NOTICE, "transmit not supported in secondary");
> + once = false;
> + }
> + rte_pktmbuf_free_bulk(bufs, nb_pkts);
> + return nb_pkts;
> +}
> +
> static uint16_t
> bond_ethdev_rx_burst(void *queue, struct rte_mbuf **bufs, uint16_t nb_pkts)
> {
> @@ -1599,6 +1626,11 @@ bond_ethdev_mode_set(struct rte_eth_dev *eth_dev,
> uint8_t mode)
> {
> struct bond_dev_private *internals;
>
> + if (rte_eal_process_type() == RTE_PROC_SECONDARY) {
> + RTE_BOND_LOG(ERR, "Setting mode in secondary not allowed");
> + return -1;
> + }
> +
> internals = eth_dev->data->dev_private;
>
> switch (mode) {
> @@ -3799,9 +3831,18 @@ bond_probe(struct rte_vdev_device *dev)
> RTE_BOND_LOG(ERR, "Failed to probe %s", name);
> return -1;
> }
> - /* TODO: request info from primary to set up Rx and Tx */
> +
> eth_dev->dev_ops = &default_dev_ops;
> eth_dev->device = &dev->device;
> +
> + /*
> + * Propagation of bond mode would require adding
> + * MP client/server support and lots of error handling.
> + *
> + * For now just install a black hole.
> + */
> + eth_dev->tx_pkt_burst = bond_ethdev_tx_secondary;
> + eth_dev->rx_pkt_burst = bond_ethdev_rx_secondary;
> rte_eth_dev_probing_finish(eth_dev);
> return 0;
> }
> --
> 2.53.0
>