summaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorAlexander Chernavin <achernavin@netgate.com>2023-05-22 14:27:24 +0000
committerMatthew Smith <mgsmith@netgate.com>2023-10-13 18:39:00 +0000
commit8a92b68bc8eaaec48d144fba62490a32f28eb422 (patch)
tree0191e0e25ee9344671e662dfd7bcd7d300b982ff /src/vnet
parent29aabcf8f6746b386be70f535ce28d7f3605ecca (diff)
ethernet: run callbacks for subifs too when mac changes
When MAC address changes for an interface, address change callbacks are executed for it. In turn adjacencies register a callback for MAC address changes to be able to update their rewrite strings accordingly. Subinterfaces inherit MAC address from the parent interface. When MAC address of the parent interface changes, it also implies MAC address change for its subinterfaces. The problem is that this is currently not considered when address change callbacks are executed. After MAC address change on the parent interface, packets sent from subinterfaces might have wrong source MAC address as the result of stale adjacencies. For example, ARP messages might be sent with the wrong (previous) MAC address and address resolution will fail. With this fix, when address change callbacks are executed for an interface, they will be also executed for its subinterfaces. And adjacencies will be able to update accordingly. Type: fix Change-Id: I87349698c10b9c3a31a28c0287e6dc711d9413a2 Signed-off-by: Alexander Chernavin <achernavin@netgate.com>
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/ethernet/interface.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/vnet/ethernet/interface.c b/src/vnet/ethernet/interface.c
index bf2256630f0..849024238bd 100644
--- a/src/vnet/ethernet/interface.c
+++ b/src/vnet/ethernet/interface.c
@@ -303,8 +303,17 @@ ethernet_mac_change (vnet_hw_interface_t * hi,
{
ethernet_address_change_ctx_t *cb;
+ u32 id, sw_if_index;
vec_foreach (cb, em->address_change_callbacks)
- cb->function (em, hi->sw_if_index, cb->function_opaque);
+ {
+ cb->function (em, hi->sw_if_index, cb->function_opaque);
+ /* clang-format off */
+ hash_foreach (id, sw_if_index, hi->sub_interface_sw_if_index_by_id,
+ ({
+ cb->function (em, sw_if_index, cb->function_opaque);
+ }));
+ /* clang-format on */
+ }
}
return (NULL);