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 ---