aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/ip6_output.c14
-rw-r--r--net/ipv6/xfrm6_output.c1
-rw-r--r--net/ipv6/xfrm6_policy.c4
3 files changed, 13 insertions, 6 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 0f0711417c9d..b78a53586804 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -552,13 +552,17 @@ static int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
552 skb_headroom(frag) < hlen) 552 skb_headroom(frag) < hlen)
553 goto slow_path; 553 goto slow_path;
554 554
555 /* Correct socket ownership. */
556 if (frag->sk == NULL)
557 goto slow_path;
558
559 /* Partially cloned skb? */ 555 /* Partially cloned skb? */
560 if (skb_shared(frag)) 556 if (skb_shared(frag))
561 goto slow_path; 557 goto slow_path;
558
559 BUG_ON(frag->sk);
560 if (skb->sk) {
561 sock_hold(skb->sk);
562 frag->sk = skb->sk;
563 frag->destructor = sock_wfree;
564 skb->truesize -= frag->truesize;
565 }
562 } 566 }
563 567
564 err = 0; 568 err = 0;
@@ -1116,12 +1120,10 @@ int ip6_push_pending_frames(struct sock *sk)
1116 tail_skb = &(tmp_skb->next); 1120 tail_skb = &(tmp_skb->next);
1117 skb->len += tmp_skb->len; 1121 skb->len += tmp_skb->len;
1118 skb->data_len += tmp_skb->len; 1122 skb->data_len += tmp_skb->len;
1119#if 0 /* Logically correct, but useless work, ip_fragment() will have to undo */
1120 skb->truesize += tmp_skb->truesize; 1123 skb->truesize += tmp_skb->truesize;
1121 __sock_put(tmp_skb->sk); 1124 __sock_put(tmp_skb->sk);
1122 tmp_skb->destructor = NULL; 1125 tmp_skb->destructor = NULL;
1123 tmp_skb->sk = NULL; 1126 tmp_skb->sk = NULL;
1124#endif
1125 } 1127 }
1126 1128
1127 ipv6_addr_copy(final_dst, &fl->fl6_dst); 1129 ipv6_addr_copy(final_dst, &fl->fl6_dst);
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c
index 601a148f60f3..6b9867717d11 100644
--- a/net/ipv6/xfrm6_output.c
+++ b/net/ipv6/xfrm6_output.c
@@ -84,6 +84,7 @@ static int xfrm6_tunnel_check_size(struct sk_buff *skb)
84 mtu = IPV6_MIN_MTU; 84 mtu = IPV6_MIN_MTU;
85 85
86 if (skb->len > mtu) { 86 if (skb->len > mtu) {
87 skb->dev = dst->dev;
87 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev); 88 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu, skb->dev);
88 ret = -EMSGSIZE; 89 ret = -EMSGSIZE;
89 } 90 }
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 4429b1a1fe5f..cf1d91e74c82 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -113,6 +113,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
113 113
114 xdst = (struct xfrm_dst *)dst1; 114 xdst = (struct xfrm_dst *)dst1;
115 xdst->route = &rt->u.dst; 115 xdst->route = &rt->u.dst;
116 if (rt->rt6i_node)
117 xdst->route_cookie = rt->rt6i_node->fn_sernum;
116 118
117 dst1->next = dst_prev; 119 dst1->next = dst_prev;
118 dst_prev = dst1; 120 dst_prev = dst1;
@@ -137,6 +139,8 @@ __xfrm6_bundle_create(struct xfrm_policy *policy, struct xfrm_state **xfrm, int
137 139
138 dst_prev->child = &rt->u.dst; 140 dst_prev->child = &rt->u.dst;
139 dst->path = &rt->u.dst; 141 dst->path = &rt->u.dst;
142 if (rt->rt6i_node)
143 ((struct xfrm_dst *)dst)->path_cookie = rt->rt6i_node->fn_sernum;
140 144
141 *dst_p = dst; 145 *dst_p = dst;
142 dst = dst_prev; 146 dst = dst_prev;