Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/klassert/ipsec

Steffen Klassert says:

====================
pull request (net): ipsec 2015-03-16

1) Fix the network header offset in _decode_session6
   when multiple IPv6 extension headers are present.
   From Hajime Tazaki.

2) Fix an interfamily tunnel crash. We set outer mode
   protocol too early and may dispatch to the wrong
   address family. Move the setting of the outer mode
   protocol behind the last accessing of the inner mode
   to fix the crash.

3) Most callers of xfrm_lookup() expect that dst_orig
   is released on error. But xfrm_lookup_route() may
   need dst_orig to handle certain error cases. So
   introduce a flag that tells what should be done in
   case of error. From Huaibin Wang.

Please pull or let me know if there are problems.
====================

Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Mar 16, 2015
2 parents 10640d3 + ac37e25 commit ca00942
Show file tree
Hide file tree
Showing 5 changed files with 10 additions and 8 deletions.
1 change: 1 addition & 0 deletions include/net/dst.h
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,7 @@ void dst_init(void);
enum {
XFRM_LOOKUP_ICMP = 1 << 0,
XFRM_LOOKUP_QUEUE = 1 << 1,
XFRM_LOOKUP_KEEP_DST_REF = 1 << 2,
};

struct flowi;
Expand Down
2 changes: 1 addition & 1 deletion net/ipv4/xfrm4_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
return err;

IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
skb->protocol = htons(ETH_P_IP);

return x->outer_mode->output2(x, skb);
}
Expand All @@ -71,7 +72,6 @@ EXPORT_SYMBOL(xfrm4_prepare_output);
int xfrm4_output_finish(struct sk_buff *skb)
{
memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
skb->protocol = htons(ETH_P_IP);

#ifdef CONFIG_NETFILTER
IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
Expand Down
2 changes: 1 addition & 1 deletion net/ipv6/xfrm6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
return err;

skb->ignore_df = 1;
skb->protocol = htons(ETH_P_IPV6);

return x->outer_mode->output2(x, skb);
}
Expand All @@ -122,7 +123,6 @@ EXPORT_SYMBOL(xfrm6_prepare_output);
int xfrm6_output_finish(struct sk_buff *skb)
{
memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
skb->protocol = htons(ETH_P_IPV6);

#ifdef CONFIG_NETFILTER
IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
Expand Down
1 change: 1 addition & 0 deletions net/ipv6/xfrm6_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ _decode_session6(struct sk_buff *skb, struct flowi *fl, int reverse)

#if IS_ENABLED(CONFIG_IPV6_MIP6)
case IPPROTO_MH:
offset += ipv6_optlen(exthdr);
if (!onlyproto && pskb_may_pull(skb, nh + offset + 3 - skb->data)) {
struct ip6_mh *mh;

Expand Down
12 changes: 6 additions & 6 deletions net/xfrm/xfrm_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -2269,11 +2269,9 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
* have the xfrm_state's. We need to wait for KM to
* negotiate new SA's or bail out with error.*/
if (net->xfrm.sysctl_larval_drop) {
dst_release(dst);
xfrm_pols_put(pols, drop_pols);
XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);

return ERR_PTR(-EREMOTE);
err = -EREMOTE;
goto error;
}

err = -EAGAIN;
Expand Down Expand Up @@ -2324,7 +2322,8 @@ struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig,
error:
dst_release(dst);
dropdst:
dst_release(dst_orig);
if (!(flags & XFRM_LOOKUP_KEEP_DST_REF))
dst_release(dst_orig);
xfrm_pols_put(pols, drop_pols);
return ERR_PTR(err);
}
Expand All @@ -2338,7 +2337,8 @@ struct dst_entry *xfrm_lookup_route(struct net *net, struct dst_entry *dst_orig,
struct sock *sk, int flags)
{
struct dst_entry *dst = xfrm_lookup(net, dst_orig, fl, sk,
flags | XFRM_LOOKUP_QUEUE);
flags | XFRM_LOOKUP_QUEUE |
XFRM_LOOKUP_KEEP_DST_REF);

if (IS_ERR(dst) && PTR_ERR(dst) == -EREMOTE)
return make_blackhole(net, dst_orig->ops->family, dst_orig);
Expand Down

0 comments on commit ca00942

Please sign in to comment.