[v2] batman-adv: use eth_hdr() instead of skb->data in interface_tx path

Message ID 1389832761-7914-1-git-send-email-linus.luessing@web.de (mailing list archive)
State Superseded, archived
Headers

Commit Message

Linus Lüssing Jan. 16, 2014, 12:39 a.m. UTC
  Using eth_hdr() instead of skb->data avoids some ugly type casts.

I wasn't able to reproduce the skb ether header pointer mismatch
mentioned in batadv_bla_tx() on a 3.11 kernel with a vlan on top of
bat0 and therefore removed the according skb_reset_mac_header()
call, too. Nevertheless I've added a check to the beginning of
batadv_interface_tx() as I guess there might potentially be some device
drivers not being that nice.

Signed-off-by: Linus Lüssing <linus.luessing@web.de>
---
v2: added missing type cast

 bridge_loop_avoidance.c |    3 ---
 soft-interface.c        |   12 +++++++++---
 2 files changed, 9 insertions(+), 6 deletions(-)
  

Comments

Marek Lindner Jan. 16, 2014, 7:06 p.m. UTC | #1
On Thursday 16 January 2014 01:39:21 Linus Lüssing wrote:
> +       if ((struct ethhdr *)skb->data != eth_hdr(skb)) {
> +               pr_warn("Upper device did not set the ethernet header
> pointer correctly - adjusting\n");
> +               skb_reset_mac_header(skb);
> +       }

How about using ratelimit or else we end up with many log messages ?

Cheers,
Marek
  
Antonio Quartulli Jan. 16, 2014, 9:07 p.m. UTC | #2
Hi Linus!

On 16/01/14 01:39, Linus Lüssing wrote:
> +	if ((struct ethhdr *)skb->data != eth_hdr(skb)) {
> +		pr_warn("Upper device did not set the ethernet header pointer correctly - adjusting\n");
> +		skb_reset_mac_header(skb);
> +	}

I think that if we really want to properly set the mac_header we should
just do it and forget about the if and about the warning.

It's a really "stupid" operation and in the end we have many spots in
the kernel where the pointers are just set without adding too much
overhead like messages or other things...


Cheers,
  

Patch

diff --git a/bridge_loop_avoidance.c b/bridge_loop_avoidance.c
index 5c0eda4..26ec489 100644
--- a/bridge_loop_avoidance.c
+++ b/bridge_loop_avoidance.c
@@ -1535,9 +1535,6 @@  int batadv_bla_tx(struct batadv_priv *bat_priv, struct sk_buff *skb,
 	if (!atomic_read(&bat_priv->bridge_loop_avoidance))
 		goto allow;
 
-	/* in VLAN case, the mac header might not be set. */
-	skb_reset_mac_header(skb);
-
 	if (batadv_bla_process_claim(bat_priv, primary_if, skb))
 		goto handled;
 
diff --git a/soft-interface.c b/soft-interface.c
index f82c267..fd7af1c 100644
--- a/soft-interface.c
+++ b/soft-interface.c
@@ -176,7 +176,13 @@  static int batadv_interface_tx(struct sk_buff *skb,
 
 	soft_iface->trans_start = jiffies;
 	vid = batadv_get_vid(skb, 0);
-	ethhdr = (struct ethhdr *)skb->data;
+
+	if ((struct ethhdr *)skb->data != eth_hdr(skb)) {
+		pr_warn("Upper device did not set the ethernet header pointer correctly - adjusting\n");
+		skb_reset_mac_header(skb);
+	}
+
+	ethhdr = eth_hdr(skb);
 
 	switch (ntohs(ethhdr->h_proto)) {
 	case ETH_P_8021Q:
@@ -194,7 +200,7 @@  static int batadv_interface_tx(struct sk_buff *skb,
 		goto dropped;
 
 	/* skb->data might have been reallocated by batadv_bla_tx() */
-	ethhdr = (struct ethhdr *)skb->data;
+	ethhdr = eth_hdr(skb);
 
 	/* Register the client MAC in the transtable */
 	if (!is_multicast_ether_addr(ethhdr->h_source)) {
@@ -230,7 +236,7 @@  static int batadv_interface_tx(struct sk_buff *skb,
 		/* skb->data may have been modified by
 		 * batadv_gw_dhcp_recipient_get()
 		 */
-		ethhdr = (struct ethhdr *)skb->data;
+		ethhdr = eth_hdr(skb);
 		/* if gw_mode is on, broadcast any non-DHCP message.
 		 * All the DHCP packets are going to be sent as unicast
 		 */