diff options
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r-- | net/ipv6/ip6_output.c | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index fbf11562b54c..cb9df0eb4023 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c | |||
@@ -219,7 +219,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, | |||
219 | skb->mark = sk->sk_mark; | 219 | skb->mark = sk->sk_mark; |
220 | 220 | ||
221 | mtu = dst_mtu(dst); | 221 | mtu = dst_mtu(dst); |
222 | if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) { | 222 | if ((skb->len <= mtu) || skb->ignore_df || skb_is_gso(skb)) { |
223 | IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)), | 223 | IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)), |
224 | IPSTATS_MIB_OUT, skb->len); | 224 | IPSTATS_MIB_OUT, skb->len); |
225 | return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, | 225 | return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, |
@@ -347,11 +347,11 @@ static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) | |||
347 | if (skb->len <= mtu) | 347 | if (skb->len <= mtu) |
348 | return false; | 348 | return false; |
349 | 349 | ||
350 | /* ipv6 conntrack defrag sets max_frag_size + local_df */ | 350 | /* ipv6 conntrack defrag sets max_frag_size + ignore_df */ |
351 | if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu) | 351 | if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu) |
352 | return true; | 352 | return true; |
353 | 353 | ||
354 | if (skb->local_df) | 354 | if (skb->ignore_df) |
355 | return false; | 355 | return false; |
356 | 356 | ||
357 | if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) | 357 | if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) |
@@ -537,6 +537,18 @@ static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from) | |||
537 | skb_copy_secmark(to, from); | 537 | skb_copy_secmark(to, from); |
538 | } | 538 | } |
539 | 539 | ||
540 | static void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt) | ||
541 | { | ||
542 | static u32 ip6_idents_hashrnd __read_mostly; | ||
543 | u32 hash, id; | ||
544 | |||
545 | net_get_random_once(&ip6_idents_hashrnd, sizeof(ip6_idents_hashrnd)); | ||
546 | |||
547 | hash = __ipv6_addr_jhash(&rt->rt6i_dst.addr, ip6_idents_hashrnd); | ||
548 | id = ip_idents_reserve(hash, 1); | ||
549 | fhdr->identification = htonl(id); | ||
550 | } | ||
551 | |||
540 | int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | 552 | int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) |
541 | { | 553 | { |
542 | struct sk_buff *frag; | 554 | struct sk_buff *frag; |
@@ -559,7 +571,7 @@ int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) | |||
559 | /* We must not fragment if the socket is set to force MTU discovery | 571 | /* We must not fragment if the socket is set to force MTU discovery |
560 | * or if the skb it not generated by a local socket. | 572 | * or if the skb it not generated by a local socket. |
561 | */ | 573 | */ |
562 | if (unlikely(!skb->local_df && skb->len > mtu) || | 574 | if (unlikely(!skb->ignore_df && skb->len > mtu) || |
563 | (IP6CB(skb)->frag_max_size && | 575 | (IP6CB(skb)->frag_max_size && |
564 | IP6CB(skb)->frag_max_size > mtu)) { | 576 | IP6CB(skb)->frag_max_size > mtu)) { |
565 | if (skb->sk && dst_allfrag(skb_dst(skb))) | 577 | if (skb->sk && dst_allfrag(skb_dst(skb))) |
@@ -1234,7 +1246,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to, | |||
1234 | sizeof(struct frag_hdr) : 0) + | 1246 | sizeof(struct frag_hdr) : 0) + |
1235 | rt->rt6i_nfheader_len; | 1247 | rt->rt6i_nfheader_len; |
1236 | 1248 | ||
1237 | if (ip6_sk_local_df(sk)) | 1249 | if (ip6_sk_ignore_df(sk)) |
1238 | maxnonfragsize = sizeof(struct ipv6hdr) + IPV6_MAXPLEN; | 1250 | maxnonfragsize = sizeof(struct ipv6hdr) + IPV6_MAXPLEN; |
1239 | else | 1251 | else |
1240 | maxnonfragsize = mtu; | 1252 | maxnonfragsize = mtu; |
@@ -1544,7 +1556,7 @@ int ip6_push_pending_frames(struct sock *sk) | |||
1544 | } | 1556 | } |
1545 | 1557 | ||
1546 | /* Allow local fragmentation. */ | 1558 | /* Allow local fragmentation. */ |
1547 | skb->local_df = ip6_sk_local_df(sk); | 1559 | skb->ignore_df = ip6_sk_ignore_df(sk); |
1548 | 1560 | ||
1549 | *final_dst = fl6->daddr; | 1561 | *final_dst = fl6->daddr; |
1550 | __skb_pull(skb, skb_network_header_len(skb)); | 1562 | __skb_pull(skb, skb_network_header_len(skb)); |