Skip to content

Commit e628cb6

Browse files
committed
bond: remove port from members on destroy
When deleting a port interface which is part of a bond, a dangling pointer is left in the bond members array. This causes crashes when destroying the bond: Program terminated with signal SIGSEGV, Segmentation fault. error reading variable: Cannot access memory at address 0xc Thread 1 (Thread 0x7f2f5cb51bc0 (LWP 657645)): #0 rte_arch_bswap16 at ../subprojects/dpdk/lib/eal/x86/include/rte_byteorder.h:30 #1 bond_update_active_members at ../modules/infra/control/bond.c:248 DPDK#2 gr_event_push at ../main/event.c:26 DPDK#3 iface_destroy at ../modules/infra/control/iface.c:409 DPDK#4 iface_del at ../modules/infra/api/iface.c:60 Make sure to remove the member when a port is deleted. Update the primary index accordingly. Signed-off-by: Robin Jarry <[email protected]>
1 parent fb99a0c commit e628cb6

1 file changed

Lines changed: 29 additions & 3 deletions

File tree

modules/infra/control/bond.c

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ static struct iface_type iface_type_bond = {
426426
.to_api = bond_to_api,
427427
};
428428

429-
static void bond_event(uint32_t, const void *obj) {
429+
static void bond_event(uint32_t event, const void *obj) {
430430
const struct iface_info_port *port;
431431
const struct iface *iface = obj;
432432
struct iface *b;
@@ -441,15 +441,41 @@ static void bond_event(uint32_t, const void *obj) {
441441
b = iface_from_id(port->bond_iface_id);
442442
if (b == NULL)
443443
return;
444-
assert(b->type == GR_IFACE_TYPE_BOND);
444+
445+
if (event == GR_EVENT_IFACE_PRE_REMOVE) {
446+
// Remove port from bond
447+
struct iface_info_bond *bond = iface_info_bond(b);
448+
const struct iface *primary = bond->members[bond->primary_member].iface;
449+
450+
for (uint8_t i = 0; i < bond->n_members; i++) {
451+
struct bond_member *member = &bond->members[i];
452+
if (member->iface == iface && i != bond->n_members - 1) {
453+
struct bond_member *next = &bond->members[i + 1];
454+
memmove(member, next, sizeof(*next) * (bond->n_members - (i + 1)));
455+
break;
456+
}
457+
}
458+
459+
bond->n_members--;
460+
bond->primary_member = 0;
461+
462+
for (uint8_t i = 0; i < bond->n_members; i++) {
463+
struct bond_member *member = &bond->members[i];
464+
if (member->iface == primary) {
465+
bond->primary_member = i;
466+
break;
467+
}
468+
}
469+
}
445470

446471
bond_update_active_members(b);
447472
}
448473

449474
static struct gr_event_subscription bond_event_handler = {
450475
.callback = bond_event,
451-
.ev_count = 2,
476+
.ev_count = 3,
452477
.ev_types = {
478+
GR_EVENT_IFACE_PRE_REMOVE,
453479
GR_EVENT_IFACE_STATUS_UP,
454480
GR_EVENT_IFACE_STATUS_DOWN,
455481
},

0 commit comments

Comments
 (0)