Commit fc04fdb2 authored by Sven Eckelmann's avatar Sven Eckelmann Committed by Simon Wunderlich

batman-adv: Fix skbuff rcsum on packet reroute

batadv_check_unicast_ttvn may redirect a packet to itself or another
originator. This involves rewriting the ttvn and the destination address in
the batadv unicast header. These field were not yet pulled (with skb rcsum
update) and thus any change to them also requires a change in the receive
checksum.
Reported-by: default avatarMatthias Schiffer <mschiffer@universe-factory.net>
Fixes: a73105b8 ("batman-adv: improved client announcement mechanism")
Signed-off-by: default avatarSven Eckelmann <sven@narfation.org>
Signed-off-by: default avatarSimon Wunderlich <sw@simonwunderlich.de>
parent 48881ed5
...@@ -759,6 +759,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, ...@@ -759,6 +759,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
/** /**
* batadv_reroute_unicast_packet() - update the unicast header for re-routing * batadv_reroute_unicast_packet() - update the unicast header for re-routing
* @bat_priv: the bat priv with all the soft interface information * @bat_priv: the bat priv with all the soft interface information
* @skb: unicast packet to process
* @unicast_packet: the unicast header to be updated * @unicast_packet: the unicast header to be updated
* @dst_addr: the payload destination * @dst_addr: the payload destination
* @vid: VLAN identifier * @vid: VLAN identifier
...@@ -770,7 +771,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb, ...@@ -770,7 +771,7 @@ static int batadv_route_unicast_packet(struct sk_buff *skb,
* Return: true if the packet header has been updated, false otherwise * Return: true if the packet header has been updated, false otherwise
*/ */
static bool static bool
batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, struct sk_buff *skb,
struct batadv_unicast_packet *unicast_packet, struct batadv_unicast_packet *unicast_packet,
u8 *dst_addr, unsigned short vid) u8 *dst_addr, unsigned short vid)
{ {
...@@ -799,8 +800,10 @@ batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, ...@@ -799,8 +800,10 @@ batadv_reroute_unicast_packet(struct batadv_priv *bat_priv,
} }
/* update the packet header */ /* update the packet header */
skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
ether_addr_copy(unicast_packet->dest, orig_addr); ether_addr_copy(unicast_packet->dest, orig_addr);
unicast_packet->ttvn = orig_ttvn; unicast_packet->ttvn = orig_ttvn;
skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
ret = true; ret = true;
out: out:
...@@ -841,7 +844,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, ...@@ -841,7 +844,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
* the packet to * the packet to
*/ */
if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) { if (batadv_tt_local_client_is_roaming(bat_priv, ethhdr->h_dest, vid)) {
if (batadv_reroute_unicast_packet(bat_priv, unicast_packet, if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet,
ethhdr->h_dest, vid)) ethhdr->h_dest, vid))
batadv_dbg_ratelimited(BATADV_DBG_TT, batadv_dbg_ratelimited(BATADV_DBG_TT,
bat_priv, bat_priv,
...@@ -887,7 +890,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, ...@@ -887,7 +890,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
* destination can possibly be updated and forwarded towards the new * destination can possibly be updated and forwarded towards the new
* target host * target host
*/ */
if (batadv_reroute_unicast_packet(bat_priv, unicast_packet, if (batadv_reroute_unicast_packet(bat_priv, skb, unicast_packet,
ethhdr->h_dest, vid)) { ethhdr->h_dest, vid)) {
batadv_dbg_ratelimited(BATADV_DBG_TT, bat_priv, batadv_dbg_ratelimited(BATADV_DBG_TT, bat_priv,
"Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n", "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n",
...@@ -910,12 +913,14 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, ...@@ -910,12 +913,14 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv,
if (!primary_if) if (!primary_if)
return false; return false;
/* update the packet header */
skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr); ether_addr_copy(unicast_packet->dest, primary_if->net_dev->dev_addr);
unicast_packet->ttvn = curr_ttvn;
skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet));
batadv_hardif_put(primary_if); batadv_hardif_put(primary_if);
unicast_packet->ttvn = curr_ttvn;
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment