ip6_output.c (c0981b863a31a1891aa2719957983f4297770f87) | ip6_output.c (73f156a6e8c1074ac6327e0abd1169e95eb66463) |
---|---|
1/* 2 * IPv6 output functions 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on linux/net/ipv4/ip_output.c --- 205 unchanged lines hidden (view full) --- 214 hdr->saddr = fl6->saddr; 215 hdr->daddr = *first_hop; 216 217 skb->protocol = htons(ETH_P_IPV6); 218 skb->priority = sk->sk_priority; 219 skb->mark = sk->sk_mark; 220 221 mtu = dst_mtu(dst); | 1/* 2 * IPv6 output functions 3 * Linux INET6 implementation 4 * 5 * Authors: 6 * Pedro Roque <roque@di.fc.ul.pt> 7 * 8 * Based on linux/net/ipv4/ip_output.c --- 205 unchanged lines hidden (view full) --- 214 hdr->saddr = fl6->saddr; 215 hdr->daddr = *first_hop; 216 217 skb->protocol = htons(ETH_P_IPV6); 218 skb->priority = sk->sk_priority; 219 skb->mark = sk->sk_mark; 220 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)), 224 IPSTATS_MIB_OUT, skb->len); 225 return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, 226 dst->dev, dst_output); 227 } 228 229 skb->dev = dst->dev; 230 ipv6_local_error(sk, EMSGSIZE, fl6, mtu); --- 111 unchanged lines hidden (view full) --- 342 return mtu; 343} 344 345static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) 346{ 347 if (skb->len <= mtu) 348 return false; 349 | 223 IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)), 224 IPSTATS_MIB_OUT, skb->len); 225 return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL, 226 dst->dev, dst_output); 227 } 228 229 skb->dev = dst->dev; 230 ipv6_local_error(sk, EMSGSIZE, fl6, mtu); --- 111 unchanged lines hidden (view full) --- 342 return mtu; 343} 344 345static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) 346{ 347 if (skb->len <= mtu) 348 return false; 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) 352 return true; 353 | 351 if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu) 352 return true; 353 |
354 if (skb->local_df) | 354 if (skb->ignore_df) |
355 return false; 356 357 if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) 358 return false; 359 360 return true; 361} 362 --- 169 unchanged lines hidden (view full) --- 532 533#ifdef CONFIG_NET_SCHED 534 to->tc_index = from->tc_index; 535#endif 536 nf_copy(to, from); 537 skb_copy_secmark(to, from); 538} 539 | 355 return false; 356 357 if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) 358 return false; 359 360 return true; 361} 362 --- 169 unchanged lines hidden (view full) --- 532 533#ifdef CONFIG_NET_SCHED 534 to->tc_index = from->tc_index; 535#endif 536 nf_copy(to, from); 537 skb_copy_secmark(to, from); 538} 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 *)) 541{ 542 struct sk_buff *frag; 543 struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); 544 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; 545 struct ipv6hdr *tmp_hdr; 546 struct frag_hdr *fh; 547 unsigned int mtu, hlen, left, len; --- 6 unchanged lines hidden (view full) --- 554 hlen = ip6_find_1stfragopt(skb, &prevhdr); 555 nexthdr = *prevhdr; 556 557 mtu = ip6_skb_dst_mtu(skb); 558 559 /* 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. 561 */ | 552int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *)) 553{ 554 struct sk_buff *frag; 555 struct rt6_info *rt = (struct rt6_info*)skb_dst(skb); 556 struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL; 557 struct ipv6hdr *tmp_hdr; 558 struct frag_hdr *fh; 559 unsigned int mtu, hlen, left, len; --- 6 unchanged lines hidden (view full) --- 566 hlen = ip6_find_1stfragopt(skb, &prevhdr); 567 nexthdr = *prevhdr; 568 569 mtu = ip6_skb_dst_mtu(skb); 570 571 /* We must not fragment if the socket is set to force MTU discovery 572 * or if the skb it not generated by a local socket. 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 && 564 IP6CB(skb)->frag_max_size > mtu)) { 565 if (skb->sk && dst_allfrag(skb_dst(skb))) 566 sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK); 567 568 skb->dev = skb_dst(skb)->dev; 569 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); 570 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), --- 658 unchanged lines hidden (view full) --- 1229 unsigned int maxnonfragsize, headersize; 1230 1231 headersize = sizeof(struct ipv6hdr) + 1232 (opt ? opt->opt_flen + opt->opt_nflen : 0) + 1233 (dst_allfrag(&rt->dst) ? 1234 sizeof(struct frag_hdr) : 0) + 1235 rt->rt6i_nfheader_len; 1236 | 575 (IP6CB(skb)->frag_max_size && 576 IP6CB(skb)->frag_max_size > mtu)) { 577 if (skb->sk && dst_allfrag(skb_dst(skb))) 578 sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK); 579 580 skb->dev = skb_dst(skb)->dev; 581 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); 582 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), --- 658 unchanged lines hidden (view full) --- 1241 unsigned int maxnonfragsize, headersize; 1242 1243 headersize = sizeof(struct ipv6hdr) + 1244 (opt ? opt->opt_flen + opt->opt_nflen : 0) + 1245 (dst_allfrag(&rt->dst) ? 1246 sizeof(struct frag_hdr) : 0) + 1247 rt->rt6i_nfheader_len; 1248 |
1237 if (ip6_sk_local_df(sk)) | 1249 if (ip6_sk_ignore_df(sk)) |
1238 maxnonfragsize = sizeof(struct ipv6hdr) + IPV6_MAXPLEN; 1239 else 1240 maxnonfragsize = mtu; 1241 1242 /* dontfrag active */ 1243 if ((cork->length + length > mtu - headersize) && dontfrag && 1244 (sk->sk_protocol == IPPROTO_UDP || 1245 sk->sk_protocol == IPPROTO_RAW)) { --- 293 unchanged lines hidden (view full) --- 1539 skb->len += tmp_skb->len; 1540 skb->data_len += tmp_skb->len; 1541 skb->truesize += tmp_skb->truesize; 1542 tmp_skb->destructor = NULL; 1543 tmp_skb->sk = NULL; 1544 } 1545 1546 /* Allow local fragmentation. */ | 1250 maxnonfragsize = sizeof(struct ipv6hdr) + IPV6_MAXPLEN; 1251 else 1252 maxnonfragsize = mtu; 1253 1254 /* dontfrag active */ 1255 if ((cork->length + length > mtu - headersize) && dontfrag && 1256 (sk->sk_protocol == IPPROTO_UDP || 1257 sk->sk_protocol == IPPROTO_RAW)) { --- 293 unchanged lines hidden (view full) --- 1551 skb->len += tmp_skb->len; 1552 skb->data_len += tmp_skb->len; 1553 skb->truesize += tmp_skb->truesize; 1554 tmp_skb->destructor = NULL; 1555 tmp_skb->sk = NULL; 1556 } 1557 1558 /* Allow local fragmentation. */ |
1547 skb->local_df = ip6_sk_local_df(sk); | 1559 skb->ignore_df = ip6_sk_ignore_df(sk); |
1548 1549 *final_dst = fl6->daddr; 1550 __skb_pull(skb, skb_network_header_len(skb)); 1551 if (opt && opt->opt_flen) 1552 ipv6_push_frag_opts(skb, opt, &proto); 1553 if (opt && opt->opt_nflen) 1554 ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst); 1555 --- 53 unchanged lines hidden --- | 1560 1561 *final_dst = fl6->daddr; 1562 __skb_pull(skb, skb_network_header_len(skb)); 1563 if (opt && opt->opt_flen) 1564 ipv6_push_frag_opts(skb, opt, &proto); 1565 if (opt && opt->opt_nflen) 1566 ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst); 1567 --- 53 unchanged lines hidden --- |