Re: [PATCH net v2] net: Reset MAC header for direct packet transmission
From: Eric Dumazet <edumazet@google.com>
Date: 2021-03-29 12:14:39
On Mon, Mar 29, 2021 at 12:30 PM Kurt Kanzenbach [off-list ref] wrote:
On Mon Mar 29 2021, Eric Dumazet wrote:quoted
Note that last year, I addressed the issue differently in commit 96cc4b69581db68efc9749ef32e9cf8e0160c509 ("macvlan: do not assume mac_header is set in macvlan_broadcast()") (amended with commit 1712b2fff8c682d145c7889d2290696647d82dab "macvlan: use skb_reset_mac_header() in macvlan_queue_xmit()") My reasoning was that in TX path, when ndo_start_xmit() is called, MAC header is essentially skb->data, so I was hoping to _remove_ skb_reset_mac_header(skb) eventually from the fast path (aka __dev_queue_xmit), because most drivers do not care about MAC header, they just use skb->data. I understand it is more difficult to review drivers instead of just adding more code in __dev_direct_xmit() In hsr case, I do not really see why the existing check can not be simply reworked ?It can be reworked, no problem. I just thought it might be better to add it to the generic code just in case there are more drivers suffering from the issue.
Note that I have a similar issue pending in ipvlan. Still, I think I prefer the non easy way to not add more stuff in fast path.
quoted
mac_header really makes sense in input path, when some layer wants to get it after it has been pulled.diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index ed82a470b6e154be28d7e53be57019bccd4a964d..cda495cb1471e23e6666c1f2e9d27a01694f997f100644--- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c@@ -555,11 +555,7 @@ void hsr_forward_skb(struct sk_buff *skb, structhsr_port *port) { struct hsr_frame_info frame; - if (skb_mac_header(skb) != skb->data) { - WARN_ONCE(1, "%s:%d: Malformed frame (port_src %s)\n", - __FILE__, __LINE__, port->dev->name); - goto out_drop; - } + skb_reset_mac_header(skb);hsr_forward_skb() has four call sites. Three of them make sure that the header is properly set. The Tx path does not. So, maybe something like below?
Yes, this should be fine.
quoted hunk ↗ jump to hunk
Thanks, Kurtdiff --git a/net/hsr/hsr_device.c b/net/hsr/hsr_device.c index 7444ec6e298e..bfcdc75fc01e 100644 --- a/net/hsr/hsr_device.c +++ b/net/hsr/hsr_device.c@@ -217,6 +217,7 @@ static netdev_tx_t hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev) master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); if (master) { skb->dev = master->dev; + skb_reset_mac_header(skb); hsr_forward_skb(skb, master); } else { atomic_long_inc(&dev->tx_dropped);diff --git a/net/hsr/hsr_forward.c b/net/hsr/hsr_forward.c index ed82a470b6e1..b218e4594009 100644 --- a/net/hsr/hsr_forward.c +++ b/net/hsr/hsr_forward.c@@ -555,12 +555,6 @@ void hsr_forward_skb(struct sk_buff *skb, struct hsr_port *port) { struct hsr_frame_info frame; - if (skb_mac_header(skb) != skb->data) { - WARN_ONCE(1, "%s:%d: Malformed frame (port_src %s)\n", - __FILE__, __LINE__, port->dev->name); - goto out_drop; - } -