aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/ip6_output.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/ip6_output.c')
-rw-r--r--net/ipv6/ip6_output.c24
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
540static 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
540int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 552int 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));