[v2] batman-adv: use eth_hdr() instead of skb->data in interface_tx path
Commit Message
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
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
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,
@@ -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;
@@ -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
*/