* [PATCH RFC 0/1] macvlan: allow source mode devices along with passthru @ 2026-06-12 9:23 Thomas Martitz 2026-06-12 9:23 ` [PATCH RFC 1/1] " Thomas Martitz 2026-07-02 6:56 ` [PATCH RESEND RFC 0/1] " Thomas Martitz 0 siblings, 2 replies; 11+ messages in thread From: Thomas Martitz @ 2026-06-12 9:23 UTC (permalink / raw) To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, open list:NETWORKING DRIVERS, open list Cc: Thomas Martitz, open list:NETWORKING DRIVERS, open list Hello, we're trying to solve a use case on our devices where two SoC are connected on the same board, using the only available high-speed. One SoC runs the main Linux system including the full routing stack (FRITZ!OS) and the other SoC implements most of the GPON ONT side. The high-speed interface is of course also used for the user traffic. Therefore we must tell the inter-SoC traffic apart from the user traffic. We achieve this by matching the well-known MAC address of the ONT SoC. The user traffic passes through the ONT SoC without modifying MAC headers. Now we would like to use macvlan (with source mode devices) on the main SoC side for this but our routing stack requires the rx_handler to be available. Therefore macvlan is currently not an option. With this patch macvlan becomes an option because the current limitation of either "one passthru device" or "any other configuration" is relaxed for the combination of passthru and any number of source mode devices. This allows us to configure a source mode device for the other SoC and register an rx_handler for further processing on the passthru device. The patch is still in an RFC state. I am not 100% confident that all the cases where the code checks "macvlan_passthru(port)" are handled appropriately. I hope you can guide me a little bit and provide feedback on the general approach. Thanks in advance! Thomas Martitz (1): macvlan: allow source mode devices along with passthru drivers/net/macvlan.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) -- 2.54.0 ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH RFC 1/1] macvlan: allow source mode devices along with passthru 2026-06-12 9:23 [PATCH RFC 0/1] macvlan: allow source mode devices along with passthru Thomas Martitz @ 2026-06-12 9:23 ` Thomas Martitz 2026-07-02 6:56 ` [PATCH RESEND RFC 0/1] " Thomas Martitz 1 sibling, 0 replies; 11+ messages in thread From: Thomas Martitz @ 2026-06-12 9:23 UTC (permalink / raw) To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, open list:NETWORKING DRIVERS, open list Cc: Thomas Martitz, open list:NETWORKING DRIVERS, open list This allows for configurations where there are a few known senders in the system (e.g. multiple SoCs on the same board) along with unlimited external senders. The source mode devices represent the known senders while all external senders terminate on passthru device. Although you can still receive packets on the lower device without the need for the passthru vlan device, there are use cases where you need additional packet processing in the pipeline that hooks via rx_handler. With this the rx_handler can be attached to the passthru device while macvlan itself remains attached to the lower device. We use this to use the same physical link for inter-SoC networking and external networking. Some of our chips have no other viable link for inter-SoC traffic. Signed-off-by: Thomas Martitz <t.martitz@fritz.com> --- drivers/net/macvlan.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index c40fa331836bb..d28f9d905a84d 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1502,15 +1502,6 @@ int macvlan_common_newlink(struct net_device *dev, } port = macvlan_port_get_rtnl(lowerdev); - /* Only 1 macvlan device can be created in passthru mode */ - if (macvlan_passthru(port)) { - /* The macvlan port must be not created this time, - * still goto destroy_macvlan_port for readability. - */ - err = -EINVAL; - goto destroy_macvlan_port; - } - vlan->lowerdev = lowerdev; vlan->dev = dev; vlan->port = port; @@ -1523,10 +1514,30 @@ int macvlan_common_newlink(struct net_device *dev, if (data && data[IFLA_MACVLAN_FLAGS]) vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); + /* Only 1 macvlan device can be created in passthru mode. There may be + * additional source mode devices but nothing else at the moment. + * + * First check if adding a source mode device to an existing passthru vlan. + */ + if (macvlan_passthru(port) && vlan->mode != MACVLAN_MODE_SOURCE) { + /* The macvlan port must be not created this time, + * still goto destroy_macvlan_port for readability. + */ + err = -EINVAL; + goto destroy_macvlan_port; + } + + /* Now check if adding a passthru device to an existing set of source mode + * devices. + */ if (vlan->mode == MACVLAN_MODE_PASSTHRU) { - if (port->count) { - err = -EINVAL; - goto destroy_macvlan_port; + struct macvlan_dev *p; + + list_for_each_entry(p, &port->vlans, list) { + if (p->mode != MACVLAN_MODE_SOURCE) { + err = -EINVAL; + goto destroy_macvlan_port; + } } macvlan_set_passthru(port); eth_hw_addr_inherit(dev, lowerdev); @@ -1560,7 +1571,11 @@ int macvlan_common_newlink(struct net_device *dev, if (err) goto unregister_netdev; - list_add_tail_rcu(&vlan->list, &port->vlans); + /* macvlan_handle_frame expects the (one and only) passthru device first. */ + if (vlan->mode == MACVLAN_MODE_PASSTHRU) + list_add_rcu(&vlan->list, &port->vlans); + else + list_add_tail_rcu(&vlan->list, &port->vlans); update_port_bc_queue_len(vlan->port); netif_stacked_transfer_operstate(lowerdev, dev); linkwatch_fire_event(dev); -- 2.54.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH RESEND RFC 0/1] macvlan: allow source mode devices along with passthru 2026-06-12 9:23 [PATCH RFC 0/1] macvlan: allow source mode devices along with passthru Thomas Martitz 2026-06-12 9:23 ` [PATCH RFC 1/1] " Thomas Martitz @ 2026-07-02 6:56 ` Thomas Martitz 2026-07-02 6:56 ` [PATCH RESEND 1/1] " Thomas Martitz 2026-07-09 9:11 ` [PATCH v2 0/1] " Thomas Martitz 1 sibling, 2 replies; 11+ messages in thread From: Thomas Martitz @ 2026-07-02 6:56 UTC (permalink / raw) To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, open list:NETWORKING DRIVERS, open list Cc: Thomas Martitz, open list:NETWORKING DRIVERS, open list Hello, we're trying to solve a use case on our devices where two SoC are connected on the same board, using the only available high-speed. One SoC runs the main Linux system including the full routing stack (FRITZ!OS) and the other SoC implements most of the GPON ONT side. The high-speed interface is of course also used for the user traffic. Therefore we must tell the inter-SoC traffic apart from the user traffic. We achieve this by matching the well-known MAC address of the ONT SoC. The user traffic passes through the ONT SoC without modifying MAC headers. Now we would like to use macvlan (with source mode devices) on the main SoC side for this but our routing stack requires the rx_handler to be available. Therefore macvlan is currently not an option. With this patch macvlan becomes an option because the current limitation of either "one passthru device" or "any other configuration" is relaxed for the combination of passthru and any number of source mode devices. This allows us to configure a source mode device for the other SoC and register an rx_handler for further processing on the passthru device. The patch is still in an RFC state. I am not 100% confident that all the cases where the code checks "macvlan_passthru(port)" are handled appropriately. I hope you can guide me a little bit and provide feedback on the general approach. Thanks in advance! Thomas Martitz (1): macvlan: allow source mode devices along with passthru drivers/net/macvlan.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) -- 2.54.0 ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH RESEND 1/1] macvlan: allow source mode devices along with passthru 2026-07-02 6:56 ` [PATCH RESEND RFC 0/1] " Thomas Martitz @ 2026-07-02 6:56 ` Thomas Martitz 2026-07-08 16:43 ` Simon Horman 2026-07-09 9:11 ` [PATCH v2 0/1] " Thomas Martitz 1 sibling, 1 reply; 11+ messages in thread From: Thomas Martitz @ 2026-07-02 6:56 UTC (permalink / raw) To: Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, open list:NETWORKING DRIVERS, open list Cc: Thomas Martitz, open list:NETWORKING DRIVERS, open list This allows for configurations where there are a few known senders in the system (e.g. multiple SoCs on the same board) along with unlimited external senders. The source mode devices represent the known senders while all external senders terminate on passthru device. Although you can still receive packets on the lower device without the need for the passthru vlan device, there are use cases where you need additional packet processing in the pipeline that hooks via rx_handler. With this the rx_handler can be attached to the passthru device while macvlan itself remains attached to the lower device. We use this to use the same physical link for inter-SoC networking and external networking. Some of our chips have no other viable link for inter-SoC traffic. Signed-off-by: Thomas Martitz <t.martitz@fritz.com> --- drivers/net/macvlan.c | 41 ++++++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index c40fa331836bb..d28f9d905a84d 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -1502,15 +1502,6 @@ int macvlan_common_newlink(struct net_device *dev, } port = macvlan_port_get_rtnl(lowerdev); - /* Only 1 macvlan device can be created in passthru mode */ - if (macvlan_passthru(port)) { - /* The macvlan port must be not created this time, - * still goto destroy_macvlan_port for readability. - */ - err = -EINVAL; - goto destroy_macvlan_port; - } - vlan->lowerdev = lowerdev; vlan->dev = dev; vlan->port = port; @@ -1523,10 +1514,30 @@ int macvlan_common_newlink(struct net_device *dev, if (data && data[IFLA_MACVLAN_FLAGS]) vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); + /* Only 1 macvlan device can be created in passthru mode. There may be + * additional source mode devices but nothing else at the moment. + * + * First check if adding a source mode device to an existing passthru vlan. + */ + if (macvlan_passthru(port) && vlan->mode != MACVLAN_MODE_SOURCE) { + /* The macvlan port must be not created this time, + * still goto destroy_macvlan_port for readability. + */ + err = -EINVAL; + goto destroy_macvlan_port; + } + + /* Now check if adding a passthru device to an existing set of source mode + * devices. + */ if (vlan->mode == MACVLAN_MODE_PASSTHRU) { - if (port->count) { - err = -EINVAL; - goto destroy_macvlan_port; + struct macvlan_dev *p; + + list_for_each_entry(p, &port->vlans, list) { + if (p->mode != MACVLAN_MODE_SOURCE) { + err = -EINVAL; + goto destroy_macvlan_port; + } } macvlan_set_passthru(port); eth_hw_addr_inherit(dev, lowerdev); @@ -1560,7 +1571,11 @@ int macvlan_common_newlink(struct net_device *dev, if (err) goto unregister_netdev; - list_add_tail_rcu(&vlan->list, &port->vlans); + /* macvlan_handle_frame expects the (one and only) passthru device first. */ + if (vlan->mode == MACVLAN_MODE_PASSTHRU) + list_add_rcu(&vlan->list, &port->vlans); + else + list_add_tail_rcu(&vlan->list, &port->vlans); update_port_bc_queue_len(vlan->port); netif_stacked_transfer_operstate(lowerdev, dev); linkwatch_fire_event(dev); -- 2.54.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH RESEND 1/1] macvlan: allow source mode devices along with passthru 2026-07-02 6:56 ` [PATCH RESEND 1/1] " Thomas Martitz @ 2026-07-08 16:43 ` Simon Horman 2026-07-09 8:49 ` Thomas Martitz 0 siblings, 1 reply; 11+ messages in thread From: Simon Horman @ 2026-07-08 16:43 UTC (permalink / raw) To: t.martitz Cc: Simon Horman, andrew+netdev, davem, edumazet, kuba, pabeni, netdev, linux-kernel This is an AI-generated review of your patch. The human sending this email has considered the AI review valid, or at least plausible. Full review at: https://sashiko.dev --- macvlan: allow source mode devices along with passthru This allows for configurations where there are a few known senders in the system (e.g. multiple SoCs on the same board) along with unlimited external senders. > diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c > index c40fa331836bb..d28f9d905a84d 100644 > --- a/drivers/net/macvlan.c > +++ b/drivers/net/macvlan.c [ ... ] > @@ -1523,10 +1514,30 @@ int macvlan_common_newlink(struct net_device *dev, > if (data && data[IFLA_MACVLAN_FLAGS]) > vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); > > + /* Only 1 macvlan device can be created in passthru mode. There may be > + * additional source mode devices but nothing else at the moment. > + * > + * First check if adding a source mode device to an existing passthru vlan. > + */ > + if (macvlan_passthru(port) && vlan->mode != MACVLAN_MODE_SOURCE) { > + /* The macvlan port must be not created this time, > + * still goto destroy_macvlan_port for readability. > + */ > + err = -EINVAL; > + goto destroy_macvlan_port; > + } [Severity: High] While macvlan_common_newlink() prevents creating non-SOURCE devices on a passthru port, macvlan_changelink() does not seem to have a similar check. Can a user bypass this restriction by creating a SOURCE device and then using changelink to modify its mode to VEPA, bypassing MAC isolation? [Severity: High] With source devices and passthru devices now coexisting on the same port, functions like macvlan_open(), macvlan_stop(), and macvlan_sync_address() check the port-wide macvlan_passthru(vlan->port) flag instead of the device mode. If a user brings down a SOURCE device on a passthru port, will macvlan_stop() incorrectly take the passthru teardown path? This appears to skip dev_uc_del() and call dev_set_promiscuity(..., -1) for a device that never incremented it. > + > + /* Now check if adding a passthru device to an existing set of source mode > + * devices. > + */ > if (vlan->mode == MACVLAN_MODE_PASSTHRU) { > - if (port->count) { > - err = -EINVAL; > - goto destroy_macvlan_port; > + struct macvlan_dev *p; > + > + list_for_each_entry(p, &port->vlans, list) { > + if (p->mode != MACVLAN_MODE_SOURCE) { > + err = -EINVAL; > + goto destroy_macvlan_port; > + } > } > macvlan_set_passthru(port); [Severity: High] If a PASSTHRU device is deleted while SOURCE devices still exist on the port, macvlan_uninit() decrements port->count but does not clear MACVLAN_F_PASSTHRU. Does this leave the port in a permanently broken state where new PASSTHRU devices cannot be created, and remaining SOURCE devices continue to be mistakenly treated as passthru? > eth_hw_addr_inherit(dev, lowerdev); ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH RESEND 1/1] macvlan: allow source mode devices along with passthru 2026-07-08 16:43 ` Simon Horman @ 2026-07-09 8:49 ` Thomas Martitz 2026-07-09 15:18 ` Simon Horman 0 siblings, 1 reply; 11+ messages in thread From: Thomas Martitz @ 2026-07-09 8:49 UTC (permalink / raw) To: Simon Horman Cc: andrew+netdev, davem, edumazet, kuba, pabeni, netdev, linux-kernel Hi Simon, Am 08.07.26 um 18:43 schrieb Simon Horman: > This is an AI-generated review of your patch. The human sending this > email has considered the AI review valid, or at least plausible. > Full review at: https://sashiko.dev Thanks for feedback. The remarks are valid, I agree. I also begin to better understand the macvlan code so I'm a bit more confident now about which of the existing "macvlan_passthru" checks need treatment. I'll send an updated patch. General question though: The initial posting triggered an AI review (I see that now, I didn't know about https://sashiko.dev before). But it did not trigger an email. Can you explain why? Because I accidentally dropped the RFC tag from the mail subject? Best regards. > --- > macvlan: allow source mode devices along with passthru > > This allows for configurations where there are a few > known senders in the system (e.g. multiple SoCs on the same > board) along with unlimited external senders. > >> diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c >> index c40fa331836bb..d28f9d905a84d 100644 >> --- a/drivers/net/macvlan.c >> +++ b/drivers/net/macvlan.c > > [ ... ] > >> @@ -1523,10 +1514,30 @@ int macvlan_common_newlink(struct net_device *dev, >> if (data && data[IFLA_MACVLAN_FLAGS]) >> vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); >> >> + /* Only 1 macvlan device can be created in passthru mode. There may be >> + * additional source mode devices but nothing else at the moment. >> + * >> + * First check if adding a source mode device to an existing passthru vlan. >> + */ >> + if (macvlan_passthru(port) && vlan->mode != MACVLAN_MODE_SOURCE) { >> + /* The macvlan port must be not created this time, >> + * still goto destroy_macvlan_port for readability. >> + */ >> + err = -EINVAL; >> + goto destroy_macvlan_port; >> + } > > [Severity: High] > While macvlan_common_newlink() prevents creating non-SOURCE devices on a > passthru port, macvlan_changelink() does not seem to have a similar check. > > Can a user bypass this restriction by creating a SOURCE device and then using > changelink to modify its mode to VEPA, bypassing MAC isolation? > > [Severity: High] > With source devices and passthru devices now coexisting on the same port, > functions like macvlan_open(), macvlan_stop(), and macvlan_sync_address() > check the port-wide macvlan_passthru(vlan->port) flag instead of the device > mode. > > If a user brings down a SOURCE device on a passthru port, will macvlan_stop() > incorrectly take the passthru teardown path? This appears to skip dev_uc_del() > and call dev_set_promiscuity(..., -1) for a device that never incremented it. > >> + >> + /* Now check if adding a passthru device to an existing set of source mode >> + * devices. >> + */ >> if (vlan->mode == MACVLAN_MODE_PASSTHRU) { >> - if (port->count) { >> - err = -EINVAL; >> - goto destroy_macvlan_port; >> + struct macvlan_dev *p; >> + >> + list_for_each_entry(p, &port->vlans, list) { >> + if (p->mode != MACVLAN_MODE_SOURCE) { >> + err = -EINVAL; >> + goto destroy_macvlan_port; >> + } >> } >> macvlan_set_passthru(port); > > [Severity: High] > If a PASSTHRU device is deleted while SOURCE devices still exist on the port, > macvlan_uninit() decrements port->count but does not clear MACVLAN_F_PASSTHRU. > > Does this leave the port in a permanently broken state where new PASSTHRU > devices cannot be created, and remaining SOURCE devices continue to be > mistakenly treated as passthru? > >> eth_hw_addr_inherit(dev, lowerdev); > -- Thomas Martitz <t.martitz@fritz.com> FRITZ! Technology GmbH, Berlin (Germany) ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH RESEND 1/1] macvlan: allow source mode devices along with passthru 2026-07-09 8:49 ` Thomas Martitz @ 2026-07-09 15:18 ` Simon Horman 0 siblings, 0 replies; 11+ messages in thread From: Simon Horman @ 2026-07-09 15:18 UTC (permalink / raw) To: Thomas Martitz Cc: andrew+netdev, davem, edumazet, kuba, pabeni, netdev, linux-kernel On Thu, Jul 09, 2026 at 10:49:36AM +0200, Thomas Martitz wrote: > Hi Simon, > > Am 08.07.26 um 18:43 schrieb Simon Horman: > > This is an AI-generated review of your patch. The human sending this > > email has considered the AI review valid, or at least plausible. > > Full review at: https://sashiko.dev > > Thanks for feedback. The remarks are valid, I agree. I also begin to better > understand the macvlan code so I'm a bit more confident now about which of > the existing "macvlan_passthru" checks need treatment. I'll send an updated > patch. > > General question though: The initial posting triggered an AI review (I see > that now, I didn't know about https://sashiko.dev before). But it did not > trigger an email. Can you explain why? Because I accidentally dropped the RFC > tag from the mail subject? Hi Thomas, If I understand correctly you are asking why the sashiko.dev review wasn't automatically emailed to you. If so, I believe configuration of that feature is on a per ML basis, and it is not enabled for netdev. In principle the sashiko review(s) show up in patchwork (although, perhaps not completely reliably). I would suggest checking there. ... ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 0/1] macvlan: allow source mode devices along with passthru 2026-07-02 6:56 ` [PATCH RESEND RFC 0/1] " Thomas Martitz 2026-07-02 6:56 ` [PATCH RESEND 1/1] " Thomas Martitz @ 2026-07-09 9:11 ` Thomas Martitz 2026-07-09 9:11 ` [PATCH v2 1/1] " Thomas Martitz 2026-07-10 7:48 ` [syzbot ci] " syzbot ci 1 sibling, 2 replies; 11+ messages in thread From: Thomas Martitz @ 2026-07-09 9:11 UTC (permalink / raw) To: Simon Horman, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, open list:NETWORKING DRIVERS, open list Cc: Thomas Martitz, open list:NETWORKING DRIVERS, open list Hello, we're trying to solve a use case on our devices where two SoC are connected on the same board, using the only available high-speed interface. One SoC runs the main Linux system including the full routing stack (FRITZ!OS) and the other SoC implements most of the GPON ONT side. The high-speed interface is of course also used for the user traffic. Therefore we must tell the inter-SoC traffic apart from the user traffic. We achieve this by matching the well-known MAC address of the ONT SoC. The user traffic passes through the ONT SoC without modifying MAC headers. Now we would like to use macvlan (with source mode devices) on the main SoC side for this but our routing stack requires the rx_handler to be available. Therefore macvlan is currently not an option. With this patch macvlan becomes an option because the current limitation of either "one passthru device" or "any other configuration" is relaxed for the combination of passthru and any number of source mode devices. This allows us to configure a source mode device for the other SoC and register an rx_handler for further processing on the passthru device. Thanks in advance! Thomas Martitz (1): macvlan: allow source mode devices along with passthru drivers/net/macvlan.c | 107 ++++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 34 deletions(-) -- 2.54.0 ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 1/1] macvlan: allow source mode devices along with passthru 2026-07-09 9:11 ` [PATCH v2 0/1] " Thomas Martitz @ 2026-07-09 9:11 ` Thomas Martitz 2026-07-10 7:48 ` [syzbot ci] " syzbot ci 1 sibling, 0 replies; 11+ messages in thread From: Thomas Martitz @ 2026-07-09 9:11 UTC (permalink / raw) To: Simon Horman, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, open list:NETWORKING DRIVERS, open list Cc: Thomas Martitz, open list:NETWORKING DRIVERS, open list This allows for configurations where there are a few known senders in the system (e.g. multiple SoCs on the same board) along with unlimited external senders. The source mode devices represent the known senders while all external senders terminate on passthru device. Although you could still receive packets on the lower device without the need for the passthru vlan device, there are use cases where you need additional packet processing in the pipeline that hooks via rx_handler. But the rx_handler is already bound to the macvlan port. With this patch the rx_handler can be attached to the passthru device while macvlan itself remains attached to the lower device. We use this to use the share the only available high-speed interface for inter-SoC networking and external networking (user traffic). Inter-SoC packets are received on the source mode interface, identified by a well-known source address. Some of our chips have simply no other viable link for inter-SoC traffic. Signed-off-by: Thomas Martitz <t.martitz@fritz.com> --- drivers/net/macvlan.c | 107 ++++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 34 deletions(-) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 9a4bc99dbf53b..2505f5f2e9d30 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -83,6 +83,11 @@ static inline void macvlan_set_passthru(struct macvlan_port *port) port->flags |= MACVLAN_F_PASSTHRU; } +static inline void macvlan_clear_passthru(struct macvlan_port *port) +{ + port->flags &= ~MACVLAN_F_PASSTHRU; +} + static inline bool macvlan_addr_change(const struct macvlan_port *port) { return port->flags & MACVLAN_F_ADDRCHANGE; @@ -637,7 +642,7 @@ static int macvlan_open(struct net_device *dev) struct net_device *lowerdev = vlan->lowerdev; int err; - if (macvlan_passthru(vlan->port)) { + if (vlan->mode == MACVLAN_MODE_PASSTHRU) { if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC)) { err = dev_set_promiscuity(lowerdev, 1); if (err < 0) @@ -712,7 +717,7 @@ static int macvlan_stop(struct net_device *dev) dev_uc_unsync(lowerdev, dev); dev_mc_unsync(lowerdev, dev); - if (macvlan_passthru(vlan->port)) { + if (vlan->mode == MACVLAN_MODE_PASSTHRU) { if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC)) dev_set_promiscuity(lowerdev, -1); goto hash_del; @@ -792,6 +797,23 @@ static int macvlan_set_mac_address(struct net_device *dev, void *p) return macvlan_sync_address(dev, addr->__data); } +static void macvlan_port_release_mac(struct net_device *dev) +{ + struct macvlan_port *port = macvlan_port_get_rtnl(dev); + + /* If the lower device address has been changed by passthru + * macvlan, put it back. + */ + if (macvlan_passthru(port) && + !ether_addr_equal(port->dev->dev_addr, port->perm_addr)) { + struct sockaddr_storage ss; + + ss.ss_family = port->dev->type; + memcpy(&ss.__data, port->perm_addr, port->dev->addr_len); + dev_set_mac_address(port->dev, &ss, NULL); + } +} + static void macvlan_change_rx_flags(struct net_device *dev, int change) { struct macvlan_dev *vlan = netdev_priv(dev); @@ -977,8 +999,18 @@ static void macvlan_uninit(struct net_device *dev) macvlan_flush_sources(port, vlan); port->count -= 1; - if (!port->count) - macvlan_port_destroy(port->dev); + if (port->count) { + /* In case of remaining source interfaces undo + * passthru-specific properties. + */ + if (vlan->mode == MACVLAN_MODE_PASSTHRU) { + macvlan_port_release_mac(dev); + macvlan_clear_passthru(vlan->port); + } + return; + } + + macvlan_port_destroy(port->dev); } static void macvlan_dev_get_stats64(struct net_device *dev, @@ -1052,7 +1084,7 @@ static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], /* Support unicast filter only on passthru devices. * Multicast filter should be allowed on all devices. */ - if (!macvlan_passthru(vlan->port) && is_unicast_ether_addr(addr)) + if (vlan->mode != MACVLAN_MODE_PASSTHRU && is_unicast_ether_addr(addr)) return -EOPNOTSUPP; if (flags & NLM_F_REPLACE) @@ -1077,7 +1109,7 @@ static int macvlan_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], /* Support unicast filter only on passthru devices. * Multicast filter should be allowed on all devices. */ - if (!macvlan_passthru(vlan->port) && is_unicast_ether_addr(addr)) + if (vlan->mode != MACVLAN_MODE_PASSTHRU && is_unicast_ether_addr(addr)) return -EOPNOTSUPP; if (is_unicast_ether_addr(addr)) @@ -1308,17 +1340,7 @@ static void macvlan_port_destroy(struct net_device *dev) kfree_skb(skb); } - /* If the lower device address has been changed by passthru - * macvlan, put it back. - */ - if (macvlan_passthru(port) && - !ether_addr_equal(port->dev->dev_addr, port->perm_addr)) { - struct sockaddr_storage ss; - - ss.ss_family = port->dev->type; - memcpy(&ss.__data, port->perm_addr, port->dev->addr_len); - dev_set_mac_address(port->dev, &ss, NULL); - } + macvlan_port_release_mac(dev); kfree(port); } @@ -1506,15 +1528,6 @@ int macvlan_common_newlink(struct net_device *dev, } port = macvlan_port_get_rtnl(lowerdev); - /* Only 1 macvlan device can be created in passthru mode */ - if (macvlan_passthru(port)) { - /* The macvlan port must be not created this time, - * still goto destroy_macvlan_port for readability. - */ - err = -EINVAL; - goto destroy_macvlan_port; - } - vlan->lowerdev = lowerdev; vlan->dev = dev; vlan->port = port; @@ -1527,10 +1540,30 @@ int macvlan_common_newlink(struct net_device *dev, if (data && data[IFLA_MACVLAN_FLAGS]) vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); + /* Only 1 macvlan device can be created in passthru mode. There may be + * additional source mode devices but nothing else at the moment. + * + * First check if adding a source mode device to an existing passthru vlan. + */ + if (macvlan_passthru(port) && vlan->mode != MACVLAN_MODE_SOURCE) { + /* The macvlan port must be not created this time, + * still goto destroy_macvlan_port for readability. + */ + err = -EINVAL; + goto destroy_macvlan_port; + } + + /* Now check if adding a passthru device to an existing set of source mode + * devices. + */ if (vlan->mode == MACVLAN_MODE_PASSTHRU) { - if (port->count) { - err = -EINVAL; - goto destroy_macvlan_port; + struct macvlan_dev *p; + + list_for_each_entry(p, &port->vlans, list) { + if (p->mode != MACVLAN_MODE_SOURCE) { + err = -EINVAL; + goto destroy_macvlan_port; + } } macvlan_set_passthru(port); eth_hw_addr_inherit(dev, lowerdev); @@ -1564,7 +1597,11 @@ int macvlan_common_newlink(struct net_device *dev, if (err) goto unregister_netdev; - list_add_tail_rcu(&vlan->list, &port->vlans); + /* macvlan_handle_frame expects the (one and only) passthru device first. */ + if (vlan->mode == MACVLAN_MODE_PASSTHRU) + list_add_rcu(&vlan->list, &port->vlans); + else + list_add_tail_rcu(&vlan->list, &port->vlans); update_port_bc_queue_len(vlan->port); netif_stacked_transfer_operstate(lowerdev, dev); linkwatch_fire_event(dev); @@ -1627,9 +1664,11 @@ static int macvlan_changelink(struct net_device *dev, if (data && data[IFLA_MACVLAN_MODE]) { set_mode = true; mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); - /* Passthrough mode can't be set or cleared dynamically */ - if ((mode == MACVLAN_MODE_PASSTHRU) != - (vlan->mode == MACVLAN_MODE_PASSTHRU)) + /* Passthrough mode can't be set or cleared dynamically, + * regardless of existing source interfaces. Furthermore, source + * interfaces can't switch modes within a passhtrough port. + */ + if (macvlan_passthru(vlan->port) && mode != vlan->mode) return -EINVAL; if (vlan->mode == MACVLAN_MODE_SOURCE && vlan->mode != mode) @@ -1639,7 +1678,7 @@ static int macvlan_changelink(struct net_device *dev, if (data && data[IFLA_MACVLAN_FLAGS]) { __u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]); bool promisc = (flags ^ vlan->flags) & MACVLAN_FLAG_NOPROMISC; - if (macvlan_passthru(vlan->port) && promisc) { + if (vlan->mode == MACVLAN_MODE_PASSTHRU && promisc) { int err; if (flags & MACVLAN_FLAG_NOPROMISC) -- 2.54.0 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [syzbot ci] Re: macvlan: allow source mode devices along with passthru 2026-07-09 9:11 ` [PATCH v2 0/1] " Thomas Martitz 2026-07-09 9:11 ` [PATCH v2 1/1] " Thomas Martitz @ 2026-07-10 7:48 ` syzbot ci 1 sibling, 0 replies; 11+ messages in thread From: syzbot ci @ 2026-07-10 7:48 UTC (permalink / raw) To: andrew, davem, edumazet, horms, kuba, linux-kernel, netdev, pabeni, t.martitz Cc: syzbot, syzkaller-bugs syzbot ci has tested the following series [v2] macvlan: allow source mode devices along with passthru https://lore.kernel.org/all/20260709091138.170348-1-t.martitz@fritz.com * [PATCH v2 1/1] macvlan: allow source mode devices along with passthru and found the following issue: general protection fault in macvlan_port_release_mac Full report is available here: https://ci.syzbot.org/series/72476997-558e-41ae-b146-c05346cdd7f6 *** general protection fault in macvlan_port_release_mac tree: net-next URL: https://kernel.googlesource.com/pub/scm/linux/kernel/git/netdev/net-next.git base: fe3e786ef4eb6e47d2901f568a27bd920477bbe9 arch: amd64 compiler: Debian clang version 22.1.6 (++20260514074242+fc4aad7b5db3-1~exp1~20260514074407.73), Debian LLD 22.1.6 config: https://ci.syzbot.org/builds/0c5e2f82-62bd-40bf-a873-66f277607c07/config syz repro: https://ci.syzbot.org/findings/d5d14725-5a48-484c-876d-026175d0b21a/syz_repro batman_adv: batadv0: Removing interface: batadv_slave_1 veth1_macvtap: left promiscuous mode veth0_macvtap: left promiscuous mode veth1_vlan: left promiscuous mode veth0_vlan: left promiscuous mode Oops: general protection fault, probably for non-canonical address 0xdffffc0000000118: 0000 [#1] SMP KASAN PTI KASAN: null-ptr-deref in range [0x00000000000008c0-0x00000000000008c7] CPU: 1 UID: 0 PID: 13 Comm: kworker/u8:1 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.2-debian-1.16.2-1 04/01/2014 Workqueue: netns cleanup_net RIP: 0010:macvlan_passthru drivers/net/macvlan.c:78 [inline] RIP: 0010:macvlan_port_release_mac+0x138/0x490 drivers/net/macvlan.c:807 Code: 01 00 00 48 89 d8 48 c1 e8 03 42 80 3c 20 00 74 08 48 89 df e8 b9 30 ae fb 48 8b 1b 4c 8d b3 c0 08 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 44 02 00 00 45 8b 36 44 89 f6 83 e6 01 RSP: 0018:ffffc90000127500 EFLAGS: 00010206 RAX: 0000000000000118 RBX: 0000000000000000 RCX: ffff888102ec5940 RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000 RBP: ffffc90000127630 R08: ffffffff9032faf7 R09: 1ffffffff2065f5e R10: dffffc0000000000 R11: fffffbfff2065f5f R12: dffffc0000000000 R13: 1ffff92000024ea4 R14: 00000000000008c0 R15: ffff888109b28818 FS: 0000000000000000(0000) GS:ffff8882a9223000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffefe7250d8 CR3: 000000000e746000 CR4: 00000000000006f0 Call Trace: <TASK> macvlan_port_destroy+0x2eb/0x310 drivers/net/macvlan.c:1343 unregister_netdevice_many_notify+0x1ad2/0x2150 net/core/dev.c:12464 unregister_netdevice_many net/core/dev.c:12506 [inline] default_device_exit_batch+0x961/0x9e0 net/core/dev.c:13098 ops_exit_list net/core/net_namespace.c:205 [inline] ops_undo_list+0x4b4/0x8d0 net/core/net_namespace.c:252 cleanup_net+0x572/0x810 net/core/net_namespace.c:702 process_one_work kernel/workqueue.c:3322 [inline] process_scheduled_works+0xa8e/0x14e0 kernel/workqueue.c:3405 worker_thread+0xa47/0xfb0 kernel/workqueue.c:3486 kthread+0x388/0x470 kernel/kthread.c:436 ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158 ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:macvlan_passthru drivers/net/macvlan.c:78 [inline] RIP: 0010:macvlan_port_release_mac+0x138/0x490 drivers/net/macvlan.c:807 Code: 01 00 00 48 89 d8 48 c1 e8 03 42 80 3c 20 00 74 08 48 89 df e8 b9 30 ae fb 48 8b 1b 4c 8d b3 c0 08 00 00 4c 89 f0 48 c1 e8 03 <42> 0f b6 04 20 84 c0 0f 85 44 02 00 00 45 8b 36 44 89 f6 83 e6 01 RSP: 0018:ffffc90000127500 EFLAGS: 00010206 RAX: 0000000000000118 RBX: 0000000000000000 RCX: ffff888102ec5940 RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000 RBP: ffffc90000127630 R08: ffffffff9032faf7 R09: 1ffffffff2065f5e R10: dffffc0000000000 R11: fffffbfff2065f5f R12: dffffc0000000000 R13: 1ffff92000024ea4 R14: 00000000000008c0 R15: ffff888109b28818 FS: 0000000000000000(0000) GS:ffff8882a9223000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007ffefe7250d8 CR3: 000000000e746000 CR4: 00000000000006f0 ---------------- Code disassembly (best guess): 0: 01 00 add %eax,(%rax) 2: 00 48 89 add %cl,-0x77(%rax) 5: d8 48 c1 fmuls -0x3f(%rax) 8: e8 03 42 80 3c call 0x3c804210 d: 20 00 and %al,(%rax) f: 74 08 je 0x19 11: 48 89 df mov %rbx,%rdi 14: e8 b9 30 ae fb call 0xfbae30d2 19: 48 8b 1b mov (%rbx),%rbx 1c: 4c 8d b3 c0 08 00 00 lea 0x8c0(%rbx),%r14 23: 4c 89 f0 mov %r14,%rax 26: 48 c1 e8 03 shr $0x3,%rax * 2a: 42 0f b6 04 20 movzbl (%rax,%r12,1),%eax <-- trapping instruction 2f: 84 c0 test %al,%al 31: 0f 85 44 02 00 00 jne 0x27b 37: 45 8b 36 mov (%r14),%r14d 3a: 44 89 f6 mov %r14d,%esi 3d: 83 e6 01 and $0x1,%esi *** If these findings have caused you to resend the series or submit a separate fix, please add the following tag to your commit message: Tested-by: syzbot@syzkaller.appspotmail.com --- This report is generated by a bot. It may contain errors. syzbot ci engineers can be reached at syzkaller@googlegroups.com. To test a patch for this bug, please reply with `#syz test` (should be on a separate line). The patch should be attached to the email. Note: arguments like custom git repos and branches are not supported. ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH v2 0/1] macvlan: allow source mode devices along with passthru @ 2026-07-09 10:05 Thomas Martitz 0 siblings, 0 replies; 11+ messages in thread From: Thomas Martitz @ 2026-07-09 10:05 UTC (permalink / raw) To: Simon Horman, Andrew Lunn, David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni, open list:NETWORKING DRIVERS, open list Cc: Thomas Martitz, open list:NETWORKING DRIVERS, open list Hello, we're trying to solve a use case on our devices where two SoC are connected on the same board, using the only available high-speed interface. One SoC runs the main Linux system including the full routing stack (FRITZ!OS) and the other SoC implements most of the GPON ONT side. The high-speed interface is of course also used for the user traffic. Therefore we must tell the inter-SoC traffic apart from the user traffic. We achieve this by matching the well-known MAC address of the ONT SoC. The user traffic passes through the ONT SoC without modifying MAC headers. Now we would like to use macvlan (with source mode devices) on the main SoC side for this but our routing stack requires the rx_handler to be available. Therefore macvlan is currently not an option. With this patch macvlan becomes an option because the current limitation of either "one passthru device" or "any other configuration" is relaxed for the combination of passthru and any number of source mode devices. This allows us to configure a source mode device for the other SoC and register an rx_handler for further processing on the passthru device. Thanks in advance! Thomas Martitz (1): macvlan: allow source mode devices along with passthru drivers/net/macvlan.c | 107 ++++++++++++++++++++++++++++-------------- 1 file changed, 73 insertions(+), 34 deletions(-) -- 2.54.0 ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2026-07-10 7:48 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-06-12 9:23 [PATCH RFC 0/1] macvlan: allow source mode devices along with passthru Thomas Martitz 2026-06-12 9:23 ` [PATCH RFC 1/1] " Thomas Martitz 2026-07-02 6:56 ` [PATCH RESEND RFC 0/1] " Thomas Martitz 2026-07-02 6:56 ` [PATCH RESEND 1/1] " Thomas Martitz 2026-07-08 16:43 ` Simon Horman 2026-07-09 8:49 ` Thomas Martitz 2026-07-09 15:18 ` Simon Horman 2026-07-09 9:11 ` [PATCH v2 0/1] " Thomas Martitz 2026-07-09 9:11 ` [PATCH v2 1/1] " Thomas Martitz 2026-07-10 7:48 ` [syzbot ci] " syzbot ci -- strict thread matches above, loose matches on Subject: below -- 2026-07-09 10:05 [PATCH v2 0/1] " Thomas Martitz
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox