summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/ip6_output.c42
1 files changed, 21 insertions, 21 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 827a3f5ff3bb..fcd3c66ded16 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -195,37 +195,37 @@ int ip6_xmit(const struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
195 const struct ipv6_pinfo *np = inet6_sk(sk); 195 const struct ipv6_pinfo *np = inet6_sk(sk);
196 struct in6_addr *first_hop = &fl6->daddr; 196 struct in6_addr *first_hop = &fl6->daddr;
197 struct dst_entry *dst = skb_dst(skb); 197 struct dst_entry *dst = skb_dst(skb);
198 unsigned int head_room;
198 struct ipv6hdr *hdr; 199 struct ipv6hdr *hdr;
199 u8 proto = fl6->flowi6_proto; 200 u8 proto = fl6->flowi6_proto;
200 int seg_len = skb->len; 201 int seg_len = skb->len;
201 int hlimit = -1; 202 int hlimit = -1;
202 u32 mtu; 203 u32 mtu;
203 204
204 if (opt) { 205 head_room = sizeof(struct ipv6hdr) + LL_RESERVED_SPACE(dst->dev);
205 unsigned int head_room; 206 if (opt)
207 head_room += opt->opt_nflen + opt->opt_flen;
206 208
207 /* First: exthdrs may take lots of space (~8K for now) 209 if (unlikely(skb_headroom(skb) < head_room)) {
208 MAX_HEADER is not enough. 210 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
209 */ 211 if (!skb2) {
210 head_room = opt->opt_nflen + opt->opt_flen; 212 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
211 seg_len += head_room; 213 IPSTATS_MIB_OUTDISCARDS);
212 head_room += sizeof(struct ipv6hdr) + LL_RESERVED_SPACE(dst->dev); 214 kfree_skb(skb);
213 215 return -ENOBUFS;
214 if (skb_headroom(skb) < head_room) {
215 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
216 if (!skb2) {
217 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
218 IPSTATS_MIB_OUTDISCARDS);
219 kfree_skb(skb);
220 return -ENOBUFS;
221 }
222 if (skb->sk)
223 skb_set_owner_w(skb2, skb->sk);
224 consume_skb(skb);
225 skb = skb2;
226 } 216 }
217 if (skb->sk)
218 skb_set_owner_w(skb2, skb->sk);
219 consume_skb(skb);
220 skb = skb2;
221 }
222
223 if (opt) {
224 seg_len += opt->opt_nflen + opt->opt_flen;
225
227 if (opt->opt_flen) 226 if (opt->opt_flen)
228 ipv6_push_frag_opts(skb, opt, &proto); 227 ipv6_push_frag_opts(skb, opt, &proto);
228
229 if (opt->opt_nflen) 229 if (opt->opt_nflen)
230 ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop, 230 ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop,
231 &fl6->saddr); 231 &fl6->saddr);