-
Notifications
You must be signed in to change notification settings - Fork 23
infra: send GARP and NA on MAC address change #473
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -47,9 +47,14 @@ static int iface_vlan_reconfig( | |
| if ((cur_parent = iface_from_id(cur->parent_id)) == NULL) | ||
| return -errno; | ||
| if (set_attrs & GR_VLAN_SET_MAC) { | ||
| // reconfig, *not initial config* | ||
| // remove previous mac filter (ignore errors) | ||
| iface_del_eth_addr(cur_parent, &cur->mac); | ||
| struct rte_ether_addr parent_mac; | ||
| if (iface_get_eth_addr(cur_parent, &parent_mac) == 0 | ||
| && rte_is_same_ether_addr(&parent_mac, &cur->mac)) { | ||
| // inherited/primary MAC: nothing to delete | ||
| } else { | ||
| // remove previous mac filter (ignore errors) | ||
| iface_del_eth_addr(cur_parent, &cur->mac); | ||
| } | ||
| } | ||
| } else { | ||
| cur_parent = NULL; | ||
|
|
@@ -90,15 +95,8 @@ static int iface_vlan_reconfig( | |
| } | ||
|
|
||
| if (set_attrs & GR_VLAN_SET_MAC) { | ||
| struct iface *parent = iface_from_id(cur->parent_id); | ||
| if (rte_is_zero_ether_addr(&next->mac)) { | ||
| if ((ret = iface_get_eth_addr(parent, &cur->mac)) < 0) | ||
| return ret; | ||
| } else { | ||
| if ((ret = iface_add_eth_addr(parent, &next->mac)) < 0) | ||
| return ret; | ||
| cur->mac = next->mac; | ||
| } | ||
| if ((ret = iface_set_eth_addr(iface, &next->mac)) < 0) | ||
| return ret; | ||
| } | ||
|
Comment on lines
97
to
100
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. VLAN MAC inheritance is cached, so parent MAC changes can make VLAN advertise the wrong MAC (plus missing NULL guards).
Also, A robust fix is to persist “inherit” vs “explicit” in VLAN private state and make Proposed direction (requires adding an inherit flag in
|
||
|
|
||
| return 0; | ||
|
|
@@ -157,6 +155,23 @@ static int iface_vlan_get_eth_addr(const struct iface *iface, struct rte_ether_a | |
| return 0; | ||
| } | ||
|
|
||
| static int iface_vlan_set_eth_addr(struct iface *iface, const struct rte_ether_addr *mac) { | ||
| struct iface_info_vlan *vlan = iface_info_vlan(iface); | ||
| struct iface *parent = iface_from_id(vlan->parent_id); | ||
| int ret; | ||
|
|
||
| if (rte_is_zero_ether_addr(mac)) { | ||
| if ((ret = iface_get_eth_addr(parent, &vlan->mac)) < 0) | ||
| return ret; | ||
| } else { | ||
| if ((ret = iface_add_eth_addr(parent, mac)) < 0) | ||
| return ret; | ||
| vlan->mac = *mac; | ||
| } | ||
|
|
||
| return 0; | ||
| } | ||
|
|
||
| static int iface_vlan_add_eth_addr(struct iface *iface, const struct rte_ether_addr *mac) { | ||
| const struct iface_info_vlan *vlan = iface_info_vlan(iface); | ||
| struct iface *parent = iface_from_id(vlan->parent_id); | ||
|
|
@@ -194,6 +209,7 @@ static struct iface_type iface_type_vlan = { | |
| .fini = iface_vlan_fini, | ||
| .set_up_down = iface_vlan_up_down, | ||
| .get_eth_addr = iface_vlan_get_eth_addr, | ||
| .set_eth_addr = iface_vlan_set_eth_addr, | ||
| .add_eth_addr = iface_vlan_add_eth_addr, | ||
| .del_eth_addr = iface_vlan_del_eth_addr, | ||
| .to_api = vlan_to_api, | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MAC_CHANGE propagation can trigger GARP/NA with a stale L2 source on inheriting subinterfaces (e.g., VLAN).
GR_EVENT_IFACE_MAC_CHANGEis forwarded toiface->subinterfaces(Line 520-524), but nothing here ensures subinterfaces that inherit the parent MAC refresh their effective MAC before IPv4/IPv6 handlers react. With the current VLAN implementation,iface_vlan_get_eth_addr()returns a cachedvlan->mac, so a parent MAC change can cause neighbors to be “updated” with the old MAC (defeating the PR’s goal and potentially blackholing traffic).Fix needs to ensure “inheriting” subifaces resolve the current parent MAC when handling MAC_CHANGE (either by making their
get_eth_addrdynamic when inheriting, or by refreshing their cached MAC before emitting/handling the event).