ipv6: call ipv6_proxy_select_ident instead of ipv6_select_ident in udp6_ufo_fragment [Linux 3.16.72]

This Linux kernel change "ipv6: call ipv6_proxy_select_ident instead of ipv6_select_ident in udp6_ufo_fragment" is included in the Linux 3.16.72 release. This change is authored by Sabrina Dubroca <sd [at] queasysnail.net> on Thu Mar 19 11:22:32 2015 +0100. The commit for this change in Linux stable tree is 66d7c26 (patch) which is from upstream commit 8e199df. The same Linux upstream change may have been applied to various maintained Linux releases and you can find all Linux releases containing changes from upstream 8e199df.

ipv6: call ipv6_proxy_select_ident instead of ipv6_select_ident in udp6_ufo_fragment

commit 8e199dfd82ee097b522b00344af6448715d8ee0c upstream.

Matt Grant reported frequent crashes in ipv6_select_ident when
udp6_ufo_fragment is called from openvswitch on a skb that doesn't
have a dst_entry set.

ipv6_proxy_select_ident generates the frag_id without using the dst
associated with the skb.  This approach was suggested by Vladislav
Yasevich.

Fixes: 0508c07f5e0c ("ipv6: Select fragment id during UFO segmentation if not set.")
Cc: Vladislav Yasevich <[email protected]>
Reported-by: Matt Grant <[email protected]>
Tested-by: Matt Grant <[email protected]>
Signed-off-by: Sabrina Dubroca <[email protected]>
Acked-by: Vladislav Yasevich <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
Signed-off-by: Ben Hutchings <[email protected]>

There are 8 lines of Linux source code added/deleted in this change. Code changes to Linux kernel are as follows.

 net/ipv6/udp_offload.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/net/ipv6/udp_offload.c b/net/ipv6/udp_offload.c
index 8f121a5..18db8cf 100644
--- a/net/ipv6/udp_offload.c
+++ b/net/ipv6/udp_offload.c
@@ -124,11 +124,9 @@ static struct sk_buff *udp6_ufo_fragment(struct sk_buff *skb,
        fptr = (struct frag_hdr *)(skb_network_header(skb) + unfrag_ip6hlen);
        fptr->nexthdr = nexthdr;
        fptr->reserved = 0;
-       if (skb_shinfo(skb)->ip6_frag_id)
-           fptr->identification = skb_shinfo(skb)->ip6_frag_id;
-       else
-           ipv6_select_ident(fptr,
-                     (struct rt6_info *)skb_dst(skb));
+       if (!skb_shinfo(skb)->ip6_frag_id)
+           ipv6_proxy_select_ident(skb);
+       fptr->identification = skb_shinfo(skb)->ip6_frag_id;

        /* Fragment the skb. ipv6 header and the remaining fields of the
         * fragment header are updated in ipv6_gso_segment()

Leave a Reply

Your email address will not be published. Required fields are marked *