From 9b777e6b13a3f85ad0b6d2c872871b611ac5bf4f Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 25 Apr 2018 20:29:31 +0200 Subject: [PATCH] batman-adv: Merge bugfixes from 2018.1 * Fix skbuff rcsum on packet reroute * update data pointers after skb_cow() * fix header size check in batadv_dbg_arp() * Fix multicast packet loss with a single WANT_ALL_IPV4/6 flag * fix multicast-via-unicast transmission with AP isolation * fix packet loss for broadcasted DHCP packets to a server Signed-off-by: Sven Eckelmann --- batman-adv/Makefile | 2 +- ...ulticast-packet-loss-with-a-single-W.patch | 38 ++++++++ ...v-update-data-pointers-after-skb_cow.patch | 61 +++++++++++++ ...-header-size-check-in-batadv_dbg_arp.patch | 30 +++++++ ...v-Fix-skbuff-rcsum-on-packet-reroute.patch | 86 +++++++++++++++++++ ...ulticast-via-unicast-transmission-wi.patch | 42 +++++++++ ...acket-loss-for-broadcasted-DHCP-pack.patch | 82 ++++++++++++++++++ 7 files changed, 340 insertions(+), 1 deletion(-) create mode 100644 batman-adv/patches/0031-batman-adv-Fix-multicast-packet-loss-with-a-single-W.patch create mode 100644 batman-adv/patches/0032-batman-adv-update-data-pointers-after-skb_cow.patch create mode 100644 batman-adv/patches/0033-batman-adv-fix-header-size-check-in-batadv_dbg_arp.patch create mode 100644 batman-adv/patches/0034-batman-adv-Fix-skbuff-rcsum-on-packet-reroute.patch create mode 100644 batman-adv/patches/0035-batman-adv-fix-multicast-via-unicast-transmission-wi.patch create mode 100644 batman-adv/patches/0036-batman-adv-fix-packet-loss-for-broadcasted-DHCP-pack.patch diff --git a/batman-adv/Makefile b/batman-adv/Makefile index a4ad65c..246fa98 100644 --- a/batman-adv/Makefile +++ b/batman-adv/Makefile @@ -11,7 +11,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=batman-adv PKG_VERSION:=2016.5 -PKG_RELEASE:=6 +PKG_RELEASE:=7 PKG_MD5SUM:=6717a933a08dd2a01b00df30cb9f16a8 PKG_HASH:=d0a0fc90c4f410b57d043215e253bb0b855efa5edbe165d87c17bfdcfafd0db7 diff --git a/batman-adv/patches/0031-batman-adv-Fix-multicast-packet-loss-with-a-single-W.patch b/batman-adv/patches/0031-batman-adv-Fix-multicast-packet-loss-with-a-single-W.patch new file mode 100644 index 0000000..0b1f17b --- /dev/null +++ b/batman-adv/patches/0031-batman-adv-Fix-multicast-packet-loss-with-a-single-W.patch @@ -0,0 +1,38 @@ +From: Linus Lüssing +Date: Sun, 4 Mar 2018 13:08:17 +0100 +Subject: [PATCH] batman-adv: Fix multicast packet loss with a single WANT_ALL_IPV4/6 flag + +As the kernel doc describes too the code is supposed to skip adding +multicast TT entries if both the WANT_ALL_IPV4 and WANT_ALL_IPV6 flags +are present. + +Unfortunately, the current code even skips adding multicast TT entries +if only either the WANT_ALL_IPV4 or WANT_ALL_IPV6 is present. + +This could lead to IPv6 multicast packet loss if only an IGMP but not an +MLD querier is present for instance or vice versa. + +Fixes: 391b59cdb111 ("batman-adv: Add multicast optimization support for bridged setups") +Signed-off-by: Linus Lüssing +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/edba00d56efb1d55cdd40957e010fba80580b5e2 +--- + net/batman-adv/multicast.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c +index 090a69fc342eac8a0b6bf89556d2b32523817d09..1fb4f87be11e984f3a839c0b2dea939cd692b04d 100644 +--- a/net/batman-adv/multicast.c ++++ b/net/batman-adv/multicast.c +@@ -541,8 +541,8 @@ update: + bat_priv->mcast.enabled = true; + } + +- return !(mcast_data.flags & +- (BATADV_MCAST_WANT_ALL_IPV4 | BATADV_MCAST_WANT_ALL_IPV6)); ++ return !(mcast_data.flags & BATADV_MCAST_WANT_ALL_IPV4 && ++ mcast_data.flags & BATADV_MCAST_WANT_ALL_IPV6); + } + + /** diff --git a/batman-adv/patches/0032-batman-adv-update-data-pointers-after-skb_cow.patch b/batman-adv/patches/0032-batman-adv-update-data-pointers-after-skb_cow.patch new file mode 100644 index 0000000..e8a522c --- /dev/null +++ b/batman-adv/patches/0032-batman-adv-update-data-pointers-after-skb_cow.patch @@ -0,0 +1,61 @@ +From: Matthias Schiffer +Date: Fri, 16 Mar 2018 11:29:09 +0100 +Subject: [PATCH] batman-adv: update data pointers after skb_cow() + +batadv_check_unicast_ttvn() calls skb_cow(), so pointers into the SKB data +must be (re)set after calling it. The ethhdr variable is dropped +altogether. + +Fixes: 78fc6bbe0aca ("batman-adv: add UNICAST_4ADDR packet type") +Signed-off-by: Matthias Schiffer +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/64d22c76a207ed313b2496f0709b2567719452c4 +--- + net/batman-adv/routing.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c +index 213cc01ad00392f7cbd4efd9d4796f76691d2d9e..8d927931017e53d285d9c64b4b850bb1d0388e11 100644 +--- a/net/batman-adv/routing.c ++++ b/net/batman-adv/routing.c +@@ -946,14 +946,10 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, + struct batadv_orig_node *orig_node = NULL, *orig_node_gw = NULL; + int check, hdr_size = sizeof(*unicast_packet); + enum batadv_subtype subtype; +- struct ethhdr *ethhdr; + int ret = NET_RX_DROP; + bool is4addr, is_gw; + + unicast_packet = (struct batadv_unicast_packet *)skb->data; +- unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; +- ethhdr = eth_hdr(skb); +- + is4addr = unicast_packet->packet_type == BATADV_UNICAST_4ADDR; + /* the caller function should have already pulled 2 bytes */ + if (is4addr) +@@ -973,12 +969,14 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, + if (!batadv_check_unicast_ttvn(bat_priv, skb, hdr_size)) + goto free_skb; + ++ unicast_packet = (struct batadv_unicast_packet *)skb->data; ++ + /* packet for me */ + if (batadv_is_my_mac(bat_priv, unicast_packet->dest)) { + /* If this is a unicast packet from another backgone gw, + * drop it. + */ +- orig_addr_gw = ethhdr->h_source; ++ orig_addr_gw = eth_hdr(skb)->h_source; + orig_node_gw = batadv_orig_hash_find(bat_priv, orig_addr_gw); + if (orig_node_gw) { + is_gw = batadv_bla_is_backbone_gw(skb, orig_node_gw, +@@ -993,6 +991,8 @@ int batadv_recv_unicast_packet(struct sk_buff *skb, + } + + if (is4addr) { ++ unicast_4addr_packet = ++ (struct batadv_unicast_4addr_packet *)skb->data; + subtype = unicast_4addr_packet->subtype; + batadv_dat_inc_counter(bat_priv, subtype); + diff --git a/batman-adv/patches/0033-batman-adv-fix-header-size-check-in-batadv_dbg_arp.patch b/batman-adv/patches/0033-batman-adv-fix-header-size-check-in-batadv_dbg_arp.patch new file mode 100644 index 0000000..bb114ba --- /dev/null +++ b/batman-adv/patches/0033-batman-adv-fix-header-size-check-in-batadv_dbg_arp.patch @@ -0,0 +1,30 @@ +From: Matthias Schiffer +Date: Fri, 16 Mar 2018 11:29:10 +0100 +Subject: [PATCH] batman-adv: fix header size check in batadv_dbg_arp() + +Checking for 0 is insufficient: when an SKB without a batadv header, but +with a VLAN header is received, hdr_size will be 4, making the following +code interpret the Ethernet header as a batadv header. + +Fixes: 3e26722bc9f2 ("batman-adv: make the Distributed ARP Table vlan aware") +Signed-off-by: Matthias Schiffer +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/7dfe729b169b1217f47744edbd1616f473340fda +--- + net/batman-adv/distributed-arp-table.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/net/batman-adv/distributed-arp-table.c b/net/batman-adv/distributed-arp-table.c +index 4d982e63a3ab269e3d3b1e7a9d5f205638051603..fcd38e48a6ea74bd91b0bdd874cb5e88e661e729 100644 +--- a/net/batman-adv/distributed-arp-table.c ++++ b/net/batman-adv/distributed-arp-table.c +@@ -391,7 +391,7 @@ static void batadv_dbg_arp(struct batadv_priv *bat_priv, struct sk_buff *skb, + batadv_arp_hw_src(skb, hdr_size), &ip_src, + batadv_arp_hw_dst(skb, hdr_size), &ip_dst); + +- if (hdr_size == 0) ++ if (hdr_size < sizeof(struct batadv_unicast_packet)) + return; + + unicast_4addr_packet = (struct batadv_unicast_4addr_packet *)skb->data; diff --git a/batman-adv/patches/0034-batman-adv-Fix-skbuff-rcsum-on-packet-reroute.patch b/batman-adv/patches/0034-batman-adv-Fix-skbuff-rcsum-on-packet-reroute.patch new file mode 100644 index 0000000..9080028 --- /dev/null +++ b/batman-adv/patches/0034-batman-adv-Fix-skbuff-rcsum-on-packet-reroute.patch @@ -0,0 +1,86 @@ +From: Sven Eckelmann +Date: Sun, 18 Mar 2018 13:12:01 +0100 +Subject: [PATCH] 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: Matthias Schiffer +Fixes: cea194d90b11 ("batman-adv: improved client announcement mechanism") +Signed-off-by: Sven Eckelmann + +Origin: backport, https://git.open-mesh.org/batman-adv.git/commit/fb91b0ef84738102807e5dd7ec0b3565415aff56 +--- + net/batman-adv/routing.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +diff --git a/net/batman-adv/routing.c b/net/batman-adv/routing.c +index 8d927931017e53d285d9c64b4b850bb1d0388e11..6a12612463127f501ad6a0df20632f14586075bd 100644 +--- a/net/batman-adv/routing.c ++++ b/net/batman-adv/routing.c +@@ -744,6 +744,7 @@ free_skb: + /** + * batadv_reroute_unicast_packet - update the unicast header for re-routing + * @bat_priv: the bat priv with all the soft interface information ++ * @skb: unicast packet to process + * @unicast_packet: the unicast header to be updated + * @dst_addr: the payload destination + * @vid: VLAN identifier +@@ -755,7 +756,7 @@ free_skb: + * Return: true if the packet header has been updated, false otherwise + */ + 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, + u8 *dst_addr, unsigned short vid) + { +@@ -784,8 +785,10 @@ batadv_reroute_unicast_packet(struct batadv_priv *bat_priv, + } + + /* update the packet header */ ++ skb_postpull_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); + ether_addr_copy(unicast_packet->dest, orig_addr); + unicast_packet->ttvn = orig_ttvn; ++ skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); + + ret = true; + out: +@@ -826,7 +829,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, + * the packet to + */ + 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)) + batadv_dbg_ratelimited(BATADV_DBG_TT, + bat_priv, +@@ -872,7 +875,7 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, + * destination can possibly be updated and forwarded towards the new + * 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)) { + batadv_dbg_ratelimited(BATADV_DBG_TT, bat_priv, + "Rerouting unicast packet to %pM (dst=%pM): TTVN mismatch old_ttvn=%u new_ttvn=%u\n", +@@ -895,12 +898,14 @@ static bool batadv_check_unicast_ttvn(struct batadv_priv *bat_priv, + if (!primary_if) + 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); ++ unicast_packet->ttvn = curr_ttvn; ++ skb_postpush_rcsum(skb, unicast_packet, sizeof(*unicast_packet)); + + batadv_hardif_put(primary_if); + +- unicast_packet->ttvn = curr_ttvn; +- + return true; + } + diff --git a/batman-adv/patches/0035-batman-adv-fix-multicast-via-unicast-transmission-wi.patch b/batman-adv/patches/0035-batman-adv-fix-multicast-via-unicast-transmission-wi.patch new file mode 100644 index 0000000..e08ab65 --- /dev/null +++ b/batman-adv/patches/0035-batman-adv-fix-multicast-via-unicast-transmission-wi.patch @@ -0,0 +1,42 @@ +From: Linus Lüssing +Date: Tue, 20 Mar 2018 03:13:27 +0100 +Subject: [PATCH] batman-adv: fix multicast-via-unicast transmission with AP isolation + +For multicast frames AP isolation is only supposed to be checked on +the receiving nodes and never on the originating one. + +Furthermore, the isolation or wifi flag bits should only be intepreted +as such for unicast and never multicast TT entries. + +By injecting flags to the multicast TT entry claimed by a single +target node it was verified in tests that this multicast address +becomes unreachable, leading to packet loss. + +Omitting the "src" parameter to the batadv_transtable_search() call +successfully skipped the AP isolation check and made the target +reachable again. + +Fixes: 405cc1e5a81e ("batman-adv: Modified forwarding behaviour for multicast packets") +Signed-off-by: Linus Lüssing +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/67a50c93bceb534937d6a188eded79272ff6d55d +--- + net/batman-adv/multicast.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/net/batman-adv/multicast.c b/net/batman-adv/multicast.c +index 1fb4f87be11e984f3a839c0b2dea939cd692b04d..20680e1dafc46cd60766a6dcd4f401f097ad4786 100644 +--- a/net/batman-adv/multicast.c ++++ b/net/batman-adv/multicast.c +@@ -811,8 +811,8 @@ static struct batadv_orig_node * + batadv_mcast_forw_tt_node_get(struct batadv_priv *bat_priv, + struct ethhdr *ethhdr) + { +- return batadv_transtable_search(bat_priv, ethhdr->h_source, +- ethhdr->h_dest, BATADV_NO_FLAGS); ++ return batadv_transtable_search(bat_priv, NULL, ethhdr->h_dest, ++ BATADV_NO_FLAGS); + } + + /** diff --git a/batman-adv/patches/0036-batman-adv-fix-packet-loss-for-broadcasted-DHCP-pack.patch b/batman-adv/patches/0036-batman-adv-fix-packet-loss-for-broadcasted-DHCP-pack.patch new file mode 100644 index 0000000..b75fb50 --- /dev/null +++ b/batman-adv/patches/0036-batman-adv-fix-packet-loss-for-broadcasted-DHCP-pack.patch @@ -0,0 +1,82 @@ +From: Linus Lüssing +Date: Thu, 22 Mar 2018 00:21:32 +0100 +Subject: [PATCH] batman-adv: fix packet loss for broadcasted DHCP packets to a server + +DHCP connectivity issues can currently occur if the following conditions +are met: + +1) A DHCP packet from a client to a server +2) This packet has a multicast destination +3) This destination has a matching entry in the translation table + (FF:FF:FF:FF:FF:FF for IPv4, 33:33:00:01:00:02/33:33:00:01:00:03 + for IPv6) +4) The orig-node determined by TT for the multicast destination + does not match the orig-node determined by best-gateway-selection + +In this case the DHCP packet will be dropped. + +The "gateway-out-of-range" check is supposed to only be applied to +unicasted DHCP packets to a specific DHCP server. + +In that case dropping the the unicasted frame forces the client to +retry via a broadcasted one, but now directed to the new best +gateway. + +A DHCP packet with broadcast/multicast destination is already ensured to +always be delivered to the best gateway. Dropping a multicasted +DHCP packet here will only prevent completing DHCP as there is no +other fallback. + +So far, it seems the unicast check was implicitly performed by +expecting the batadv_transtable_search() to return NULL for multicast +destinations. However, a multicast address could have always ended up in +the translation table and in fact is now common. + +To fix this potential loss of a DHCP client-to-server packet to a +multicast address this patch adds an explicit multicast destination +check to reliably bail out of the gateway-out-of-range check for such +destinations. + +The issue and fix were tested in the following three node setup: + +- Line topology, A-B-C +- A: gateway client, DHCP client +- B: gateway server, hop-penalty increased: 30->60, DHCP server +- C: gateway server, code modifications to announce FF:FF:FF:FF:FF:FF + +Without this patch, A would never transmit its DHCP Discover packet +due to an always "out-of-range" condition. With this patch, +a full DHCP handshake between A and B was possible again. + +Fixes: afae4e42aae6 ("batman-adv: refactoring gateway handling code") +Signed-off-by: Linus Lüssing +Signed-off-by: Sven Eckelmann + +Origin: upstream, https://git.open-mesh.org/batman-adv.git/commit/49b2132f0fe2753a3b46103db9719898c5cd44aa +--- + net/batman-adv/gateway_client.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c +index 52b8bd6ec43183519a63483950c2e886e47a6f9e..f1fdf4e7f5c3ce7f20339dcee3b6e43290ea3b4e 100644 +--- a/net/batman-adv/gateway_client.c ++++ b/net/batman-adv/gateway_client.c +@@ -705,7 +705,7 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, + { + struct batadv_neigh_node *neigh_curr = NULL; + struct batadv_neigh_node *neigh_old = NULL; +- struct batadv_orig_node *orig_dst_node; ++ struct batadv_orig_node *orig_dst_node = NULL; + struct batadv_gw_node *gw_node = NULL; + struct batadv_gw_node *curr_gw = NULL; + struct batadv_neigh_ifinfo *curr_ifinfo, *old_ifinfo; +@@ -716,6 +716,9 @@ bool batadv_gw_out_of_range(struct batadv_priv *bat_priv, + + vid = batadv_get_vid(skb, 0); + ++ if (is_multicast_ether_addr(ethhdr->h_dest)) ++ goto out; ++ + orig_dst_node = batadv_transtable_search(bat_priv, ethhdr->h_source, + ethhdr->h_dest, vid); + if (!orig_dst_node)