Lines Matching +full:conntrack +full:- +full:related

1 // SPDX-License-Identifier: GPL-2.0-or-later
21 * : add ip6_append_data and related functions
38 #include <linux/bpf-cgroup.h>
63 struct net_device *dev = dst->dev; in ip6_finish_output2()
72 if (unlikely(hh_len > skb_headroom(skb)) && dev->header_ops) { in ip6_finish_output2()
79 return -ENOMEM; in ip6_finish_output2()
85 daddr = &hdr->daddr; in ip6_finish_output2()
87 if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(sk) && in ip6_finish_output2()
89 !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || in ip6_finish_output2()
90 ipv6_chk_mcast_addr(dev, daddr, &hdr->saddr))) { in ip6_finish_output2()
98 net, sk, newskb, NULL, newskb->dev, in ip6_finish_output2()
101 if (hdr->hop_limit == 0) { in ip6_finish_output2()
109 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUTMCAST, skb->len); in ip6_finish_output2()
111 !(dev->flags & IFF_LOOPBACK)) { in ip6_finish_output2()
117 if (lwtunnel_xmit_redirect(dst->lwtstate)) { in ip6_finish_output2()
124 IP6_UPD_PO_STATS(net, idev, IPSTATS_MIB_OUT, skb->len); in ip6_finish_output2()
137 return -EINVAL; in ip6_finish_output2()
162 return -ENOMEM; in ip6_finish_output_gso_slowpath_drop()
173 * which is considered harmful (RFC-8021). Avoid that. in ip6_finish_output_gso_slowpath_drop()
175 err = segs->len > mtu ? in ip6_finish_output_gso_slowpath_drop()
188 if (!(IP6CB(skb)->flags & IP6SKB_FAKEJUMBO) && in ip6_finish_output_gso()
201 if (skb_dst(skb)->xfrm) { in __ip6_finish_output()
202 IP6CB(skb)->flags |= IP6SKB_REROUTED; in __ip6_finish_output()
211 if (skb->len > mtu || in __ip6_finish_output()
212 (IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size)) in __ip6_finish_output()
235 struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev; in ip6_output()
238 skb->protocol = htons(ETH_P_IPV6); in ip6_output()
239 skb->dev = dev; in ip6_output()
241 if (unlikely(!idev || READ_ONCE(idev->cnf.disable_ipv6))) { in ip6_output()
250 !(IP6CB(skb)->flags & IP6SKB_REROUTED)); in ip6_output()
272 struct in6_addr *first_hop = &fl6->daddr; in ip6_xmit()
274 struct net_device *dev = dst->dev; in ip6_xmit()
280 u8 proto = fl6->flowi6_proto; in ip6_xmit()
281 int seg_len = skb->len; in ip6_xmit()
282 int hlimit = -1; in ip6_xmit()
287 head_room += opt->opt_nflen + opt->opt_flen; in ip6_xmit()
296 return -ENOBUFS; in ip6_xmit()
302 seg_len += opt->opt_nflen + opt->opt_flen; in ip6_xmit()
304 if (opt->opt_flen) in ip6_xmit()
307 if (opt->opt_nflen) in ip6_xmit()
309 &fl6->saddr); in ip6_xmit()
315 hop_jumbo->nexthdr = proto; in ip6_xmit()
316 hop_jumbo->hdrlen = 0; in ip6_xmit()
317 hop_jumbo->tlv_type = IPV6_TLV_JUMBO; in ip6_xmit()
318 hop_jumbo->tlv_len = 4; in ip6_xmit()
319 hop_jumbo->jumbo_payload_len = htonl(seg_len + hoplen); in ip6_xmit()
323 IP6CB(skb)->flags |= IP6SKB_FAKEJUMBO; in ip6_xmit()
334 hlimit = READ_ONCE(np->hop_limit); in ip6_xmit()
338 ip6_flow_hdr(hdr, tclass, ip6_make_flowlabel(net, skb, fl6->flowlabel, in ip6_xmit()
341 hdr->payload_len = htons(seg_len); in ip6_xmit()
342 hdr->nexthdr = proto; in ip6_xmit()
343 hdr->hop_limit = hlimit; in ip6_xmit()
345 hdr->saddr = fl6->saddr; in ip6_xmit()
346 hdr->daddr = *first_hop; in ip6_xmit()
348 skb->protocol = htons(ETH_P_IPV6); in ip6_xmit()
349 skb->priority = priority; in ip6_xmit()
350 skb->mark = mark; in ip6_xmit()
353 if ((skb->len <= mtu) || skb->ignore_df || skb_is_gso(skb)) { in ip6_xmit()
371 skb->dev = dev; in ip6_xmit()
379 return -EMSGSIZE; in ip6_xmit()
389 for (ra = ip6_ra_chain; ra; ra = ra->next) { in ip6_call_ra_chain()
390 struct sock *sk = ra->sk; in ip6_call_ra_chain()
391 if (sk && ra->sel == sel && in ip6_call_ra_chain()
392 (!sk->sk_bound_dev_if || in ip6_call_ra_chain()
393 sk->sk_bound_dev_if == skb->dev->ifindex)) { in ip6_call_ra_chain()
396 !net_eq(sock_net(sk), dev_net(skb->dev))) { in ip6_call_ra_chain()
420 u8 nexthdr = hdr->nexthdr; in ip6_forward_proxy_check()
435 offset + 1 - skb->data))) in ip6_forward_proxy_check()
440 switch (icmp6->icmp6_type) { in ip6_forward_proxy_check()
457 * The proxying router can't forward traffic sent to a link-local in ip6_forward_proxy_check()
461 if (ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) { in ip6_forward_proxy_check()
463 return -1; in ip6_forward_proxy_check()
473 if (skb->offload_l3_fwd_mark) { in ip6_forward_finish()
485 if (skb->len <= mtu) in ip6_pkt_too_big()
488 /* ipv6 conntrack defrag sets max_frag_size + ignore_df */ in ip6_pkt_too_big()
489 if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu) in ip6_pkt_too_big()
492 if (skb->ignore_df) in ip6_pkt_too_big()
506 struct net *net = dev_net(dst->dev); in ip6_forward()
511 idev = __in6_dev_get_safely(dev_get_by_index_rcu(net, IP6CB(skb)->iif)); in ip6_forward()
512 if (READ_ONCE(net->ipv6.devconf_all->forwarding) == 0) in ip6_forward()
515 if (skb->pkt_type != PACKET_HOST) in ip6_forward()
518 if (unlikely(skb->sk)) in ip6_forward()
524 if (!READ_ONCE(net->ipv6.devconf_all->disable_policy) && in ip6_forward()
525 (!idev || !READ_ONCE(idev->cnf.disable_policy)) && in ip6_forward()
540 * We are not end-node, so that if packet contains in ip6_forward()
544 * that different fragments will go along one path. --ANK in ip6_forward()
546 if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) { in ip6_forward()
547 if (ip6_call_ra_chain(skb, ntohs(opt->ra))) in ip6_forward()
554 if (hdr->hop_limit <= 1) { in ip6_forward()
559 return -ETIMEDOUT; in ip6_forward()
562 /* XXX: idev->cnf.proxy_ndp? */ in ip6_forward()
563 if (READ_ONCE(net->ipv6.devconf_all->proxy_ndp) && in ip6_forward()
564 pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) { in ip6_forward()
599 if (IP6CB(skb)->iif == dst->dev->ifindex && in ip6_forward()
600 opt->srcrt == 0 && !skb_sec_path(skb)) { in ip6_forward()
611 if (rt->rt6i_flags & RTF_GATEWAY) in ip6_forward()
612 target = &rt->rt6i_gateway; in ip6_forward()
614 target = &hdr->daddr; in ip6_forward()
617 peer = inet_getpeer_v6(net->ipv6.peers, &hdr->daddr); in ip6_forward()
626 int addrtype = ipv6_addr_type(&hdr->saddr); in ip6_forward()
647 skb->dev = dst->dev; in ip6_forward()
653 return -EMSGSIZE; in ip6_forward()
656 if (skb_cow(skb, dst->dev->hard_header_len)) { in ip6_forward()
666 hdr->hop_limit--; in ip6_forward()
669 net, NULL, skb, skb->dev, dst->dev, in ip6_forward()
677 return -EINVAL; in ip6_forward()
682 to->pkt_type = from->pkt_type; in ip6_copy_metadata()
683 to->priority = from->priority; in ip6_copy_metadata()
684 to->protocol = from->protocol; in ip6_copy_metadata()
687 to->dev = from->dev; in ip6_copy_metadata()
688 to->mark = from->mark; in ip6_copy_metadata()
693 to->tc_index = from->tc_index; in ip6_copy_metadata()
709 iter->tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); in ip6_fraglist_init()
710 if (!iter->tmp_hdr) in ip6_fraglist_init()
711 return -ENOMEM; in ip6_fraglist_init()
713 iter->frag = skb_shinfo(skb)->frag_list; in ip6_fraglist_init()
716 iter->offset = 0; in ip6_fraglist_init()
717 iter->hlen = hlen; in ip6_fraglist_init()
718 iter->frag_id = frag_id; in ip6_fraglist_init()
719 iter->nexthdr = nexthdr; in ip6_fraglist_init()
725 memcpy(skb_network_header(skb), iter->tmp_hdr, hlen); in ip6_fraglist_init()
727 fh->nexthdr = nexthdr; in ip6_fraglist_init()
728 fh->reserved = 0; in ip6_fraglist_init()
729 fh->frag_off = htons(IP6_MF); in ip6_fraglist_init()
730 fh->identification = frag_id; in ip6_fraglist_init()
733 skb->data_len = first_len - skb_headlen(skb); in ip6_fraglist_init()
734 skb->len = first_len; in ip6_fraglist_init()
735 ipv6_hdr(skb)->payload_len = htons(first_len - sizeof(struct ipv6hdr)); in ip6_fraglist_init()
744 struct sk_buff *frag = iter->frag; in ip6_fraglist_prepare()
745 unsigned int hlen = iter->hlen; in ip6_fraglist_prepare()
748 frag->ip_summed = CHECKSUM_NONE; in ip6_fraglist_prepare()
753 memcpy(skb_network_header(frag), iter->tmp_hdr, hlen); in ip6_fraglist_prepare()
754 iter->offset += skb->len - hlen - sizeof(struct frag_hdr); in ip6_fraglist_prepare()
755 fh->nexthdr = iter->nexthdr; in ip6_fraglist_prepare()
756 fh->reserved = 0; in ip6_fraglist_prepare()
757 fh->frag_off = htons(iter->offset); in ip6_fraglist_prepare()
758 if (frag->next) in ip6_fraglist_prepare()
759 fh->frag_off |= htons(IP6_MF); in ip6_fraglist_prepare()
760 fh->identification = iter->frag_id; in ip6_fraglist_prepare()
761 ipv6_hdr(frag)->payload_len = htons(frag->len - sizeof(struct ipv6hdr)); in ip6_fraglist_prepare()
770 state->prevhdr = prevhdr; in ip6_frag_init()
771 state->nexthdr = nexthdr; in ip6_frag_init()
772 state->frag_id = frag_id; in ip6_frag_init()
774 state->hlen = hlen; in ip6_frag_init()
775 state->mtu = mtu; in ip6_frag_init()
777 state->left = skb->len - hlen; /* Space per frame */ in ip6_frag_init()
778 state->ptr = hlen; /* Where to start from */ in ip6_frag_init()
780 state->hroom = hdr_room; in ip6_frag_init()
781 state->troom = needed_tailroom; in ip6_frag_init()
783 state->offset = 0; in ip6_frag_init()
789 u8 *prevhdr = state->prevhdr, *fragnexthdr_offset; in ip6_frag_next()
794 len = state->left; in ip6_frag_next()
795 /* IF: it doesn't fit, use 'mtu' - the data space left */ in ip6_frag_next()
796 if (len > state->mtu) in ip6_frag_next()
797 len = state->mtu; in ip6_frag_next()
800 if (len < state->left) in ip6_frag_next()
804 frag = alloc_skb(len + state->hlen + sizeof(struct frag_hdr) + in ip6_frag_next()
805 state->hroom + state->troom, GFP_ATOMIC); in ip6_frag_next()
807 return ERR_PTR(-ENOMEM); in ip6_frag_next()
814 skb_reserve(frag, state->hroom); in ip6_frag_next()
815 skb_put(frag, len + state->hlen + sizeof(struct frag_hdr)); in ip6_frag_next()
817 fh = (struct frag_hdr *)(skb_network_header(frag) + state->hlen); in ip6_frag_next()
818 frag->transport_header = (frag->network_header + state->hlen + in ip6_frag_next()
825 if (skb->sk) in ip6_frag_next()
826 skb_set_owner_w(frag, skb->sk); in ip6_frag_next()
831 skb_copy_from_linear_data(skb, skb_network_header(frag), state->hlen); in ip6_frag_next()
834 fragnexthdr_offset += prevhdr - skb_network_header(skb); in ip6_frag_next()
840 fh->nexthdr = state->nexthdr; in ip6_frag_next()
841 fh->reserved = 0; in ip6_frag_next()
842 fh->identification = state->frag_id; in ip6_frag_next()
847 BUG_ON(skb_copy_bits(skb, state->ptr, skb_transport_header(frag), in ip6_frag_next()
849 state->left -= len; in ip6_frag_next()
851 fh->frag_off = htons(state->offset); in ip6_frag_next()
852 if (state->left > 0) in ip6_frag_next()
853 fh->frag_off |= htons(IP6_MF); in ip6_frag_next()
854 ipv6_hdr(frag)->payload_len = htons(frag->len - sizeof(struct ipv6hdr)); in ip6_frag_next()
856 state->ptr += len; in ip6_frag_next()
857 state->offset += len; in ip6_frag_next()
868 struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ? in ip6_fragment()
869 inet6_sk(skb->sk) : NULL; in ip6_fragment()
870 u8 tstamp_type = skb->tstamp_type; in ip6_fragment()
873 ktime_t tstamp = skb->tstamp; in ip6_fragment()
883 nexthdr_offset = prevhdr - skb_network_header(skb); in ip6_fragment()
890 if (unlikely(!skb->ignore_df && skb->len > mtu)) in ip6_fragment()
893 if (IP6CB(skb)->frag_max_size) { in ip6_fragment()
894 if (IP6CB(skb)->frag_max_size > mtu) in ip6_fragment()
898 mtu = IP6CB(skb)->frag_max_size; in ip6_fragment()
904 u32 frag_size = READ_ONCE(np->frag_size); in ip6_fragment()
911 mtu -= hlen + sizeof(struct frag_hdr); in ip6_fragment()
913 frag_id = ipv6_select_ident(net, &ipv6_hdr(skb)->daddr, in ip6_fragment()
914 &ipv6_hdr(skb)->saddr); in ip6_fragment()
916 if (skb->ip_summed == CHECKSUM_PARTIAL && in ip6_fragment()
921 hroom = LL_RESERVED_SPACE(rt->dst.dev); in ip6_fragment()
927 if (first_len - hlen > mtu || in ip6_fragment()
928 ((first_len - hlen) & 7) || in ip6_fragment()
935 if (frag->len > mtu || in ip6_fragment()
936 ((frag->len & 7) && frag->next) || in ip6_fragment()
944 BUG_ON(frag->sk); in ip6_fragment()
945 if (skb->sk) { in ip6_fragment()
946 frag->sk = skb->sk; in ip6_fragment()
947 frag->destructor = sock_wfree; in ip6_fragment()
949 skb->truesize -= frag->truesize; in ip6_fragment()
969 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), in ip6_fragment()
981 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), in ip6_fragment()
989 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst), in ip6_fragment()
998 frag2->sk = NULL; in ip6_fragment()
999 frag2->destructor = NULL; in ip6_fragment()
1000 skb->truesize += frag2->truesize; in ip6_fragment()
1009 ip6_frag_init(skb, hlen, mtu, rt->dst.dev->needed_tailroom, in ip6_fragment()
1010 LL_RESERVED_SPACE(rt->dst.dev), prevhdr, nexthdr, frag_id, in ip6_fragment()
1042 err = -EMSGSIZE; in ip6_fragment()
1055 return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) && in ip6_rt_check()
1069 if (dst->ops->family != AF_INET6) { in ip6_sk_dst_check()
1078 * and MSG_DONTROUTE --ANK (980726) in ip6_sk_dst_check()
1092 if (ip6_rt_check(&rt->rt6i_dst, &fl6->daddr, np->daddr_cache) || in ip6_sk_dst_check()
1094 ip6_rt_check(&rt->rt6i_src, &fl6->saddr, np->saddr_cache) || in ip6_sk_dst_check()
1096 (fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex)) { in ip6_sk_dst_check()
1117 * the route-specific preferred source forces the in ip6_dst_lookup_tail()
1124 if (ipv6_addr_any(&fl6->saddr)) { in ip6_dst_lookup_tail()
1129 rt = (*dst)->error ? NULL : dst_rt6_info(*dst); in ip6_dst_lookup_tail()
1132 from = rt ? rcu_dereference(rt->from) : NULL; in ip6_dst_lookup_tail()
1133 err = ip6_route_get_saddr(net, from, &fl6->daddr, in ip6_dst_lookup_tail()
1134 sk ? READ_ONCE(inet6_sk(sk)->srcprefs) : 0, in ip6_dst_lookup_tail()
1135 fl6->flowi6_l3mdev, in ip6_dst_lookup_tail()
1136 &fl6->saddr); in ip6_dst_lookup_tail()
1143 * never existed and let the SA-enabled version take in ip6_dst_lookup_tail()
1146 if ((*dst)->error) { in ip6_dst_lookup_tail()
1151 if (fl6->flowi6_oif) in ip6_dst_lookup_tail()
1158 err = (*dst)->error; in ip6_dst_lookup_tail()
1173 n = __ipv6_neigh_lookup_noref(rt->dst.dev, in ip6_dst_lookup_tail()
1174 rt6_nexthop(rt, &fl6->daddr)); in ip6_dst_lookup_tail()
1175 err = n && !(READ_ONCE(n->nud_state) & NUD_VALID) ? -EINVAL : 0; in ip6_dst_lookup_tail()
1183 ifp = ipv6_get_ifaddr(net, &fl6->saddr, in ip6_dst_lookup_tail()
1184 (*dst)->dev, 1); in ip6_dst_lookup_tail()
1186 redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC); in ip6_dst_lookup_tail()
1199 err = (*dst)->error; in ip6_dst_lookup_tail()
1205 if (ipv6_addr_v4mapped(&fl6->saddr) && in ip6_dst_lookup_tail()
1206 !(ipv6_addr_v4mapped(&fl6->daddr) || ipv6_addr_any(&fl6->daddr))) { in ip6_dst_lookup_tail()
1207 err = -EAFNOSUPPORT; in ip6_dst_lookup_tail()
1217 if (err == -ENETUNREACH) in ip6_dst_lookup_tail()
1223 * ip6_dst_lookup - perform route lookup on flow
1242 * ip6_dst_lookup_flow - perform route lookup on flow with ipsec
1263 fl6->daddr = *final_dst; in ip6_dst_lookup_flow()
1270 * ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow
1291 struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie); in ip6_sk_dst_lookup_flow()
1308 return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; in ip6_opt_dup()
1314 return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL; in ip6_rthdr_dup()
1324 if (!(rt->dst.flags & DST_XFRM_TUNNEL)) { in ip6_append_data_mtu()
1327 *mtu = orig_mtu - rt->dst.header_len; in ip6_append_data_mtu()
1336 *maxfraglen = ((*mtu - fragheaderlen) & ~7) in ip6_append_data_mtu()
1337 + fragheaderlen - sizeof(struct frag_hdr); in ip6_append_data_mtu()
1347 struct ipv6_txoptions *nopt, *opt = ipc6->opt; in ip6_setup_cork()
1352 cork->base.dst = &rt->dst; in ip6_setup_cork()
1358 if (WARN_ON(v6_cork->opt)) in ip6_setup_cork()
1359 return -EINVAL; in ip6_setup_cork()
1361 nopt = v6_cork->opt = kzalloc(sizeof(*opt), sk->sk_allocation); in ip6_setup_cork()
1363 return -ENOBUFS; in ip6_setup_cork()
1365 nopt->tot_len = sizeof(*opt); in ip6_setup_cork()
1366 nopt->opt_flen = opt->opt_flen; in ip6_setup_cork()
1367 nopt->opt_nflen = opt->opt_nflen; in ip6_setup_cork()
1369 nopt->dst0opt = ip6_opt_dup(opt->dst0opt, sk->sk_allocation); in ip6_setup_cork()
1370 if (opt->dst0opt && !nopt->dst0opt) in ip6_setup_cork()
1371 return -ENOBUFS; in ip6_setup_cork()
1373 nopt->dst1opt = ip6_opt_dup(opt->dst1opt, sk->sk_allocation); in ip6_setup_cork()
1374 if (opt->dst1opt && !nopt->dst1opt) in ip6_setup_cork()
1375 return -ENOBUFS; in ip6_setup_cork()
1377 nopt->hopopt = ip6_opt_dup(opt->hopopt, sk->sk_allocation); in ip6_setup_cork()
1378 if (opt->hopopt && !nopt->hopopt) in ip6_setup_cork()
1379 return -ENOBUFS; in ip6_setup_cork()
1381 nopt->srcrt = ip6_rthdr_dup(opt->srcrt, sk->sk_allocation); in ip6_setup_cork()
1382 if (opt->srcrt && !nopt->srcrt) in ip6_setup_cork()
1383 return -ENOBUFS; in ip6_setup_cork()
1387 v6_cork->hop_limit = ipc6->hlimit; in ip6_setup_cork()
1388 v6_cork->tclass = ipc6->tclass; in ip6_setup_cork()
1389 if (rt->dst.flags & DST_XFRM_TUNNEL) in ip6_setup_cork()
1390 mtu = READ_ONCE(np->pmtudisc) >= IPV6_PMTUDISC_PROBE ? in ip6_setup_cork()
1391 READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst); in ip6_setup_cork()
1393 mtu = READ_ONCE(np->pmtudisc) >= IPV6_PMTUDISC_PROBE ? in ip6_setup_cork()
1394 READ_ONCE(rt->dst.dev->mtu) : dst_mtu(xfrm_dst_path(&rt->dst)); in ip6_setup_cork()
1396 frag_size = READ_ONCE(np->frag_size); in ip6_setup_cork()
1400 cork->base.fragsize = mtu; in ip6_setup_cork()
1401 cork->base.gso_size = ipc6->gso_size; in ip6_setup_cork()
1402 cork->base.tx_flags = 0; in ip6_setup_cork()
1403 cork->base.mark = ipc6->sockc.mark; in ip6_setup_cork()
1404 cork->base.priority = ipc6->sockc.priority; in ip6_setup_cork()
1405 sock_tx_timestamp(sk, &ipc6->sockc, &cork->base.tx_flags); in ip6_setup_cork()
1406 if (ipc6->sockc.tsflags & SOCKCM_FLAG_TS_OPT_ID) { in ip6_setup_cork()
1407 cork->base.flags |= IPCORK_TS_OPT_ID; in ip6_setup_cork()
1408 cork->base.ts_opt_id = ipc6->sockc.ts_opt_id; in ip6_setup_cork()
1410 cork->base.length = 0; in ip6_setup_cork()
1411 cork->base.transmit_time = ipc6->sockc.transmit_time; in ip6_setup_cork()
1427 struct inet_cork *cork = &cork_full->base; in __ip6_append_data()
1428 struct flowi6 *fl6 = &cork_full->fl.u.ip6; in __ip6_append_data()
1439 struct rt6_info *rt = dst_rt6_info(cork->dst); in __ip6_append_data()
1441 struct ipv6_txoptions *opt = v6_cork->opt; in __ip6_append_data()
1448 exthdrlen = opt ? opt->opt_flen : 0; in __ip6_append_data()
1449 dst_exthdrlen = rt->dst.header_len - rt->rt6i_nfheader_len; in __ip6_append_data()
1452 paged = !!cork->gso_size; in __ip6_append_data()
1453 mtu = cork->gso_size ? IP6_MAX_MTU : cork->fragsize; in __ip6_append_data()
1456 hh_len = LL_RESERVED_SPACE(rt->dst.dev); in __ip6_append_data()
1458 fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len + in __ip6_append_data()
1459 (opt ? opt->opt_nflen : 0); in __ip6_append_data()
1462 (opt ? opt->opt_flen + opt->opt_nflen : 0) + in __ip6_append_data()
1463 rt->rt6i_nfheader_len; in __ip6_append_data()
1466 ((mtu - fragheaderlen) & ~7) + fragheaderlen <= sizeof(struct frag_hdr)) in __ip6_append_data()
1469 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen - in __ip6_append_data()
1478 if (cork->length + length > mtu - headersize && ipc6->dontfrag && in __ip6_append_data()
1479 (sk->sk_protocol == IPPROTO_UDP || in __ip6_append_data()
1480 sk->sk_protocol == IPPROTO_ICMPV6 || in __ip6_append_data()
1481 sk->sk_protocol == IPPROTO_RAW)) { in __ip6_append_data()
1482 ipv6_local_rxpmtu(sk, fl6, mtu - headersize + in __ip6_append_data()
1492 if (cork->length + length > maxnonfragsize - headersize) { in __ip6_append_data()
1494 pmtu = max_t(int, mtu - headersize + sizeof(struct ipv6hdr), 0); in __ip6_append_data()
1496 return -EMSGSIZE; in __ip6_append_data()
1502 if (transhdrlen && sk->sk_protocol == IPPROTO_UDP && in __ip6_append_data()
1504 length <= mtu - headersize && in __ip6_append_data()
1505 (!(flags & MSG_MORE) || cork->gso_size) && in __ip6_append_data()
1506 rt->dst.dev->features & (NETIF_F_IPV6_CSUM | NETIF_F_HW_CSUM)) in __ip6_append_data()
1512 if (getfrag == ip_generic_getfrag && msg->msg_ubuf) { in __ip6_append_data()
1513 if (skb_zcopy(skb) && msg->msg_ubuf != skb_zcopy(skb)) in __ip6_append_data()
1514 return -EINVAL; in __ip6_append_data()
1519 if ((rt->dst.dev->features & NETIF_F_SG) && in __ip6_append_data()
1523 uarg = msg->msg_ubuf; in __ip6_append_data()
1528 return -ENOBUFS; in __ip6_append_data()
1530 if (rt->dst.dev->features & NETIF_F_SG && in __ip6_append_data()
1535 uarg_to_msgzc(uarg)->zerocopy = 0; in __ip6_append_data()
1541 return -EPERM; in __ip6_append_data()
1542 if (rt->dst.dev->features & NETIF_F_SG && in __ip6_append_data()
1550 if (cork->tx_flags & SKBTX_ANY_TSTAMP && in __ip6_append_data()
1551 READ_ONCE(sk->sk_tsflags) & SOF_TIMESTAMPING_OPT_ID) { in __ip6_append_data()
1552 if (cork->flags & IPCORK_TS_OPT_ID) { in __ip6_append_data()
1553 tskey = cork->ts_opt_id; in __ip6_append_data()
1555 tskey = atomic_inc_return(&sk->sk_tskey) - 1; in __ip6_append_data()
1564 * fragment alignment (= 8-15 octects, in total). in __ip6_append_data()
1571 * at once if non-fragmentable extension headers in __ip6_append_data()
1573 * --yoshfuji in __ip6_append_data()
1576 cork->length += length; in __ip6_append_data()
1582 copy = (cork->length <= mtu ? mtu : maxfraglen) - skb->len; in __ip6_append_data()
1584 copy = maxfraglen - skb->len; in __ip6_append_data()
1596 fraggap = skb->len - maxfraglen; in __ip6_append_data()
1613 if (datalen > (cork->length <= mtu ? mtu : maxfraglen) - fragheaderlen) in __ip6_append_data()
1614 datalen = maxfraglen - fragheaderlen - rt->dst.trailer_len; in __ip6_append_data()
1620 alloc_extra += rt->dst.trailer_len; in __ip6_append_data()
1629 !(rt->dst.dev->features&NETIF_F_SG)) in __ip6_append_data()
1633 !(rt->dst.dev->features & NETIF_F_SG))) in __ip6_append_data()
1637 pagedlen = datalen - transhdrlen; in __ip6_append_data()
1646 datalen += rt->dst.trailer_len; in __ip6_append_data()
1651 copy = datalen - transhdrlen - fraggap - pagedlen; in __ip6_append_data()
1653 * because then the equation may reduces to -fraggap. in __ip6_append_data()
1656 err = -EINVAL; in __ip6_append_data()
1664 if (refcount_read(&sk->sk_wmem_alloc) + wmem_alloc_delta <= in __ip6_append_data()
1665 2 * sk->sk_sndbuf) in __ip6_append_data()
1667 sk->sk_allocation); in __ip6_append_data()
1669 err = -ENOBUFS; in __ip6_append_data()
1676 skb->protocol = htons(ETH_P_IPV6); in __ip6_append_data()
1677 skb->ip_summed = csummode; in __ip6_append_data()
1678 skb->csum = 0; in __ip6_append_data()
1686 data = skb_put(skb, fraglen - pagedlen); in __ip6_append_data()
1689 skb->transport_header = (skb->network_header + in __ip6_append_data()
1692 skb->csum = skb_copy_and_csum_bits( in __ip6_append_data()
1695 skb_prev->csum = csum_sub(skb_prev->csum, in __ip6_append_data()
1696 skb->csum); in __ip6_append_data()
1704 err = -EFAULT; in __ip6_append_data()
1712 length -= copy + transhdrlen; in __ip6_append_data()
1718 skb_shinfo(skb)->tx_flags = cork->tx_flags; in __ip6_append_data()
1719 cork->tx_flags = 0; in __ip6_append_data()
1720 skb_shinfo(skb)->tskey = tskey; in __ip6_append_data()
1730 if (!skb->destructor) { in __ip6_append_data()
1731 skb->destructor = sock_wfree; in __ip6_append_data()
1732 skb->sk = sk; in __ip6_append_data()
1733 wmem_alloc_delta += skb->truesize; in __ip6_append_data()
1742 if (!(rt->dst.dev->features&NETIF_F_SG) && in __ip6_append_data()
1746 off = skb->len; in __ip6_append_data()
1751 err = -EFAULT; in __ip6_append_data()
1757 err = -EIO; in __ip6_append_data()
1758 if (WARN_ON_ONCE(copy > msg->msg_iter.count)) in __ip6_append_data()
1761 err = skb_splice_from_iter(skb, &msg->msg_iter, copy, in __ip6_append_data()
1762 sk->sk_allocation); in __ip6_append_data()
1768 int i = skb_shinfo(skb)->nr_frags; in __ip6_append_data()
1770 err = -ENOMEM; in __ip6_append_data()
1775 if (!skb_can_coalesce(skb, i, pfrag->page, in __ip6_append_data()
1776 pfrag->offset)) { in __ip6_append_data()
1777 err = -EMSGSIZE; in __ip6_append_data()
1781 __skb_fill_page_desc(skb, i, pfrag->page, in __ip6_append_data()
1782 pfrag->offset, 0); in __ip6_append_data()
1783 skb_shinfo(skb)->nr_frags = ++i; in __ip6_append_data()
1784 get_page(pfrag->page); in __ip6_append_data()
1786 copy = min_t(int, copy, pfrag->size - pfrag->offset); in __ip6_append_data()
1789 page_address(pfrag->page) + pfrag->offset, in __ip6_append_data()
1790 offset, copy, skb->len, skb) < 0) in __ip6_append_data()
1793 pfrag->offset += copy; in __ip6_append_data()
1794 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy); in __ip6_append_data()
1795 skb->len += copy; in __ip6_append_data()
1796 skb->data_len += copy; in __ip6_append_data()
1797 skb->truesize += copy; in __ip6_append_data()
1805 length -= copy; in __ip6_append_data()
1809 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc); in __ip6_append_data()
1813 err = -EFAULT; in __ip6_append_data()
1816 cork->length -= length; in __ip6_append_data()
1817 IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS); in __ip6_append_data()
1818 refcount_add(wmem_alloc_delta, &sk->sk_wmem_alloc); in __ip6_append_data()
1820 atomic_dec(&sk->sk_tskey); in __ip6_append_data()
1838 if (skb_queue_empty(&sk->sk_write_queue)) { in ip6_append_data()
1842 dst_hold(&rt->dst); in ip6_append_data()
1843 err = ip6_setup_cork(sk, &inet->cork, &np->cork, in ip6_append_data()
1848 inet->cork.fl.u.ip6 = *fl6; in ip6_append_data()
1849 exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0); in ip6_append_data()
1856 return __ip6_append_data(sk, &sk->sk_write_queue, &inet->cork, in ip6_append_data()
1857 &np->cork, sk_page_frag(sk), getfrag, in ip6_append_data()
1864 struct dst_entry *dst = cork->base.dst; in ip6_cork_steal_dst()
1866 cork->base.dst = NULL; in ip6_cork_steal_dst()
1873 if (v6_cork->opt) { in ip6_cork_release()
1874 struct ipv6_txoptions *opt = v6_cork->opt; in ip6_cork_release()
1876 kfree(opt->dst0opt); in ip6_cork_release()
1877 kfree(opt->dst1opt); in ip6_cork_release()
1878 kfree(opt->hopopt); in ip6_cork_release()
1879 kfree(opt->srcrt); in ip6_cork_release()
1881 v6_cork->opt = NULL; in ip6_cork_release()
1884 if (cork->base.dst) { in ip6_cork_release()
1885 dst_release(cork->base.dst); in ip6_cork_release()
1886 cork->base.dst = NULL; in ip6_cork_release()
1900 struct ipv6_txoptions *opt = v6_cork->opt; in __ip6_make_skb()
1901 struct rt6_info *rt = dst_rt6_info(cork->base.dst); in __ip6_make_skb()
1902 struct flowi6 *fl6 = &cork->fl.u.ip6; in __ip6_make_skb()
1903 unsigned char proto = fl6->flowi6_proto; in __ip6_make_skb()
1908 tail_skb = &(skb_shinfo(skb)->frag_list); in __ip6_make_skb()
1910 /* move skb->data to ip header from ext header */ in __ip6_make_skb()
1911 if (skb->data < skb_network_header(skb)) in __ip6_make_skb()
1916 tail_skb = &(tmp_skb->next); in __ip6_make_skb()
1917 skb->len += tmp_skb->len; in __ip6_make_skb()
1918 skb->data_len += tmp_skb->len; in __ip6_make_skb()
1919 skb->truesize += tmp_skb->truesize; in __ip6_make_skb()
1920 tmp_skb->destructor = NULL; in __ip6_make_skb()
1921 tmp_skb->sk = NULL; in __ip6_make_skb()
1925 skb->ignore_df = ip6_sk_ignore_df(sk); in __ip6_make_skb()
1928 final_dst = &fl6->daddr; in __ip6_make_skb()
1929 if (opt && opt->opt_flen) in __ip6_make_skb()
1931 if (opt && opt->opt_nflen) in __ip6_make_skb()
1932 ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst, &fl6->saddr); in __ip6_make_skb()
1938 ip6_flow_hdr(hdr, v6_cork->tclass, in __ip6_make_skb()
1939 ip6_make_flowlabel(net, skb, fl6->flowlabel, in __ip6_make_skb()
1941 hdr->hop_limit = v6_cork->hop_limit; in __ip6_make_skb()
1942 hdr->nexthdr = proto; in __ip6_make_skb()
1943 hdr->saddr = fl6->saddr; in __ip6_make_skb()
1944 hdr->daddr = *final_dst; in __ip6_make_skb()
1946 skb->priority = cork->base.priority; in __ip6_make_skb()
1947 skb->mark = cork->base.mark; in __ip6_make_skb()
1949 skb_set_delivery_time(skb, cork->base.transmit_time, SKB_CLOCK_MONOTONIC); in __ip6_make_skb()
1951 skb_set_delivery_type_by_clockid(skb, cork->base.transmit_time, sk->sk_clockid); in __ip6_make_skb()
1954 IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTREQUESTS); in __ip6_make_skb()
1959 if (sk->sk_socket->type == SOCK_RAW && in __ip6_make_skb()
1960 !(fl6->flowi6_flags & FLOWI_FLAG_KNOWN_NH)) in __ip6_make_skb()
1961 icmp6_type = fl6->fl6_icmp_type; in __ip6_make_skb()
1963 icmp6_type = icmp6_hdr(skb)->icmp6_type; in __ip6_make_skb()
1975 struct net *net = sock_net(skb->sk); in ip6_send_skb()
1980 err = ip6_local_out(net, skb->sk, skb); in ip6_send_skb()
1985 IP6_INC_STATS(net, rt->rt6i_idev, in ip6_send_skb()
2024 __ip6_flush_pending_frames(sk, &sk->sk_write_queue, in ip6_flush_pending_frames()
2025 &inet_sk(sk)->cork, &inet6_sk(sk)->cork); in ip6_flush_pending_frames()
2038 int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0); in ip6_make_skb()
2042 dst_release(&rt->dst); in ip6_make_skb()
2048 cork->base.flags = 0; in ip6_make_skb()
2049 cork->base.addr = 0; in ip6_make_skb()
2050 cork->base.opt = NULL; in ip6_make_skb()
2057 if (ipc6->dontfrag < 0) in ip6_make_skb()
2058 ipc6->dontfrag = inet6_test_bit(DONTFRAG, sk); in ip6_make_skb()
2061 &current->task_frag, getfrag, from, in ip6_make_skb()