Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec

Steffen Klassert says:

====================
pull request (net): ipsec 2020-05-29

1) Several fixes for ESP gro/gso in transport and beet mode when
   IPv6 extension headers are present. From Xin Long.

2) Fix a wrong comment on XFRMA_OFFLOAD_DEV.
   From Antony Antony.

3) Fix sk_destruct callback handling on ESP in TCP encapsulation.
   From Sabrina Dubroca.

4) Fix a use after free in xfrm_output_gso when used with vxlan.
   From Xin Long.

5) Fix secpath handling of VTI when used wiuth IPCOMP.
   From Xin Long.

6) Fix an oops when deleting a x-netns xfrm interface.
   From Nicolas Dichtel.

7) Fix a possible warning on policy updates. We had a case where it was
   possible to add two policies with the same lookup keys.
   From Xin Long.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller
2020-05-29 13:05:56 -07:00
11 changed files with 104 additions and 44 deletions

View File

@@ -85,10 +85,8 @@ static struct sk_buff *esp6_gro_receive(struct list_head *head,
sp->olen++;
xo = xfrm_offload(skb);
if (!xo) {
xfrm_state_put(x);
if (!xo)
goto out_reset;
}
}
xo->flags |= XFRM_GRO;
@@ -123,9 +121,16 @@ static void esp6_gso_encap(struct xfrm_state *x, struct sk_buff *skb)
struct ip_esp_hdr *esph;
struct ipv6hdr *iph = ipv6_hdr(skb);
struct xfrm_offload *xo = xfrm_offload(skb);
int proto = iph->nexthdr;
u8 proto = iph->nexthdr;
skb_push(skb, -skb_network_offset(skb));
if (x->outer_mode.encap == XFRM_MODE_TRANSPORT) {
__be16 frag;
ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &proto, &frag);
}
esph = ip_esp_hdr(skb);
*skb_mac_header(skb) = IPPROTO_ESP;
@@ -166,23 +171,31 @@ static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x,
struct xfrm_offload *xo = xfrm_offload(skb);
struct sk_buff *segs = ERR_PTR(-EINVAL);
const struct net_offload *ops;
int proto = xo->proto;
u8 proto = xo->proto;
skb->transport_header += x->props.header_len;
if (proto == IPPROTO_BEETPH) {
struct ip_beet_phdr *ph = (struct ip_beet_phdr *)skb->data;
skb->transport_header += ph->hdrlen * 8;
proto = ph->nexthdr;
}
if (x->sel.family != AF_INET6) {
skb->transport_header -=
(sizeof(struct ipv6hdr) - sizeof(struct iphdr));
if (proto == IPPROTO_BEETPH) {
struct ip_beet_phdr *ph =
(struct ip_beet_phdr *)skb->data;
skb->transport_header += ph->hdrlen * 8;
proto = ph->nexthdr;
} else {
skb->transport_header -= IPV4_BEET_PHMAXLEN;
}
if (proto == IPPROTO_TCP)
skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6;
} else {
__be16 frag;
skb->transport_header +=
ipv6_skip_exthdr(skb, 0, &proto, &frag);
}
__skb_pull(skb, skb_transport_offset(skb));