ip6_output.c (80901bff812984624918d9d03f9286e3245ee9a5) ip6_output.c (5e34af4142ffe68f01c8a9acae83300f8911e20c)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * IPv6 output functions
4 * Linux INET6 implementation
5 *
6 * Authors:
7 * Pedro Roque <roque@di.fc.ul.pt>
8 *

--- 116 unchanged lines hidden (view full) ---

125 sock_confirm_neigh(skb, neigh);
126 ret = neigh_output(neigh, skb, false);
127 rcu_read_unlock_bh();
128 return ret;
129 }
130 rcu_read_unlock_bh();
131
132 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTNOROUTES);
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * IPv6 output functions
4 * Linux INET6 implementation
5 *
6 * Authors:
7 * Pedro Roque <roque@di.fc.ul.pt>
8 *

--- 116 unchanged lines hidden (view full) ---

125 sock_confirm_neigh(skb, neigh);
126 ret = neigh_output(neigh, skb, false);
127 rcu_read_unlock_bh();
128 return ret;
129 }
130 rcu_read_unlock_bh();
131
132 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTNOROUTES);
133 kfree_skb_reason(skb, SKB_DROP_REASON_NEIGH_CREATEFAIL);
133 kfree_skb(skb);
134 return -EINVAL;
135}
136
137static int
138ip6_finish_output_gso_slowpath_drop(struct net *net, struct sock *sk,
139 struct sk_buff *skb, unsigned int mtu)
140{
141 struct sk_buff *segs, *nskb;

--- 55 unchanged lines hidden (view full) ---

197
198 ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb);
199 switch (ret) {
200 case NET_XMIT_SUCCESS:
201 return __ip6_finish_output(net, sk, skb);
202 case NET_XMIT_CN:
203 return __ip6_finish_output(net, sk, skb) ? : ret;
204 default:
134 return -EINVAL;
135}
136
137static int
138ip6_finish_output_gso_slowpath_drop(struct net *net, struct sock *sk,
139 struct sk_buff *skb, unsigned int mtu)
140{
141 struct sk_buff *segs, *nskb;

--- 55 unchanged lines hidden (view full) ---

197
198 ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb);
199 switch (ret) {
200 case NET_XMIT_SUCCESS:
201 return __ip6_finish_output(net, sk, skb);
202 case NET_XMIT_CN:
203 return __ip6_finish_output(net, sk, skb) ? : ret;
204 default:
205 kfree_skb_reason(skb, SKB_DROP_REASON_BPF_CGROUP_EGRESS);
205 kfree_skb(skb);
206 return ret;
207 }
208}
209
210int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
211{
212 struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
213 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
214
215 skb->protocol = htons(ETH_P_IPV6);
216 skb->dev = dev;
217
218 if (unlikely(idev->cnf.disable_ipv6)) {
219 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
206 return ret;
207 }
208}
209
210int ip6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
211{
212 struct net_device *dev = skb_dst(skb)->dev, *indev = skb->dev;
213 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
214
215 skb->protocol = htons(ETH_P_IPV6);
216 skb->dev = dev;
217
218 if (unlikely(idev->cnf.disable_ipv6)) {
219 IP6_INC_STATS(net, idev, IPSTATS_MIB_OUTDISCARDS);
220 kfree_skb_reason(skb, SKB_DROP_REASON_IPV6DISABLED);
220 kfree_skb(skb);
221 return 0;
222 }
223
224 return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
225 net, sk, skb, indev, dev,
226 ip6_finish_output,
227 !(IP6CB(skb)->flags & IP6SKB_REROUTED));
228}

--- 206 unchanged lines hidden (view full) ---

435
436#ifdef CONFIG_NET_SWITCHDEV
437 if (skb->offload_l3_fwd_mark) {
438 consume_skb(skb);
439 return 0;
440 }
441#endif
442
221 return 0;
222 }
223
224 return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING,
225 net, sk, skb, indev, dev,
226 ip6_finish_output,
227 !(IP6CB(skb)->flags & IP6SKB_REROUTED));
228}

--- 206 unchanged lines hidden (view full) ---

435
436#ifdef CONFIG_NET_SWITCHDEV
437 if (skb->offload_l3_fwd_mark) {
438 consume_skb(skb);
439 return 0;
440 }
441#endif
442
443 skb_clear_tstamp(skb);
443 skb->tstamp = 0;
444 return dst_output(net, sk, skb);
445}
446
447static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
448{
449 if (skb->len <= mtu)
450 return false;
451

--- 356 unchanged lines hidden (view full) ---

808
809int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
810 int (*output)(struct net *, struct sock *, struct sk_buff *))
811{
812 struct sk_buff *frag;
813 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
814 struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
815 inet6_sk(skb->sk) : NULL;
444 return dst_output(net, sk, skb);
445}
446
447static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
448{
449 if (skb->len <= mtu)
450 return false;
451

--- 356 unchanged lines hidden (view full) ---

808
809int ip6_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
810 int (*output)(struct net *, struct sock *, struct sk_buff *))
811{
812 struct sk_buff *frag;
813 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
814 struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ?
815 inet6_sk(skb->sk) : NULL;
816 bool mono_delivery_time = skb->mono_delivery_time;
817 struct ip6_frag_state state;
818 unsigned int mtu, hlen, nexthdr_offset;
819 ktime_t tstamp = skb->tstamp;
820 int hroom, err = 0;
821 __be32 frag_id;
822 u8 *prevhdr, nexthdr = 0;
823
824 err = ip6_find_1stfragopt(skb, &prevhdr);

--- 74 unchanged lines hidden (view full) ---

899 goto fail;
900
901 for (;;) {
902 /* Prepare header of the next frame,
903 * before previous one went down. */
904 if (iter.frag)
905 ip6_fraglist_prepare(skb, &iter);
906
816 struct ip6_frag_state state;
817 unsigned int mtu, hlen, nexthdr_offset;
818 ktime_t tstamp = skb->tstamp;
819 int hroom, err = 0;
820 __be32 frag_id;
821 u8 *prevhdr, nexthdr = 0;
822
823 err = ip6_find_1stfragopt(skb, &prevhdr);

--- 74 unchanged lines hidden (view full) ---

898 goto fail;
899
900 for (;;) {
901 /* Prepare header of the next frame,
902 * before previous one went down. */
903 if (iter.frag)
904 ip6_fraglist_prepare(skb, &iter);
905
907 skb_set_delivery_time(skb, tstamp, mono_delivery_time);
906 skb->tstamp = tstamp;
908 err = output(net, sk, skb);
909 if (!err)
910 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
911 IPSTATS_MIB_FRAGCREATES);
912
913 if (err || !iter.frag)
914 break;
915

--- 42 unchanged lines hidden (view full) ---

958 if (IS_ERR(frag)) {
959 err = PTR_ERR(frag);
960 goto fail;
961 }
962
963 /*
964 * Put this fragment into the sending queue.
965 */
907 err = output(net, sk, skb);
908 if (!err)
909 IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
910 IPSTATS_MIB_FRAGCREATES);
911
912 if (err || !iter.frag)
913 break;
914

--- 42 unchanged lines hidden (view full) ---

957 if (IS_ERR(frag)) {
958 err = PTR_ERR(frag);
959 goto fail;
960 }
961
962 /*
963 * Put this fragment into the sending queue.
964 */
966 skb_set_delivery_time(frag, tstamp, mono_delivery_time);
965 frag->tstamp = tstamp;
967 err = output(net, sk, frag);
968 if (err)
969 goto fail;
970
971 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
972 IPSTATS_MIB_FRAGCREATES);
973 }
974 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),

--- 371 unchanged lines hidden (view full) ---

1346 }
1347 *maxfraglen = ((*mtu - fragheaderlen) & ~7)
1348 + fragheaderlen - sizeof(struct frag_hdr);
1349 }
1350}
1351
1352static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
1353 struct inet6_cork *v6_cork, struct ipcm6_cookie *ipc6,
966 err = output(net, sk, frag);
967 if (err)
968 goto fail;
969
970 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
971 IPSTATS_MIB_FRAGCREATES);
972 }
973 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),

--- 371 unchanged lines hidden (view full) ---

1345 }
1346 *maxfraglen = ((*mtu - fragheaderlen) & ~7)
1347 + fragheaderlen - sizeof(struct frag_hdr);
1348 }
1349}
1350
1351static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
1352 struct inet6_cork *v6_cork, struct ipcm6_cookie *ipc6,
1354 struct rt6_info *rt)
1353 struct rt6_info *rt, struct flowi6 *fl6)
1355{
1356 struct ipv6_pinfo *np = inet6_sk(sk);
1357 unsigned int mtu;
1354{
1355 struct ipv6_pinfo *np = inet6_sk(sk);
1356 unsigned int mtu;
1358 struct ipv6_txoptions *nopt, *opt = ipc6->opt;
1357 struct ipv6_txoptions *opt = ipc6->opt;
1359
1358
1360 /* callers pass dst together with a reference, set it first so
1361 * ip6_cork_release() can put it down even in case of an error.
1362 */
1363 cork->base.dst = &rt->dst;
1364
1365 /*
1366 * setup for corking
1367 */
1368 if (opt) {
1369 if (WARN_ON(v6_cork->opt))
1370 return -EINVAL;
1371
1359 /*
1360 * setup for corking
1361 */
1362 if (opt) {
1363 if (WARN_ON(v6_cork->opt))
1364 return -EINVAL;
1365
1372 nopt = v6_cork->opt = kzalloc(sizeof(*opt), sk->sk_allocation);
1373 if (unlikely(!nopt))
1366 v6_cork->opt = kzalloc(sizeof(*opt), sk->sk_allocation);
1367 if (unlikely(!v6_cork->opt))
1374 return -ENOBUFS;
1375
1368 return -ENOBUFS;
1369
1376 nopt->tot_len = sizeof(*opt);
1377 nopt->opt_flen = opt->opt_flen;
1378 nopt->opt_nflen = opt->opt_nflen;
1370 v6_cork->opt->tot_len = sizeof(*opt);
1371 v6_cork->opt->opt_flen = opt->opt_flen;
1372 v6_cork->opt->opt_nflen = opt->opt_nflen;
1379
1373
1380 nopt->dst0opt = ip6_opt_dup(opt->dst0opt, sk->sk_allocation);
1381 if (opt->dst0opt && !nopt->dst0opt)
1374 v6_cork->opt->dst0opt = ip6_opt_dup(opt->dst0opt,
1375 sk->sk_allocation);
1376 if (opt->dst0opt && !v6_cork->opt->dst0opt)
1382 return -ENOBUFS;
1383
1377 return -ENOBUFS;
1378
1384 nopt->dst1opt = ip6_opt_dup(opt->dst1opt, sk->sk_allocation);
1385 if (opt->dst1opt && !nopt->dst1opt)
1379 v6_cork->opt->dst1opt = ip6_opt_dup(opt->dst1opt,
1380 sk->sk_allocation);
1381 if (opt->dst1opt && !v6_cork->opt->dst1opt)
1386 return -ENOBUFS;
1387
1382 return -ENOBUFS;
1383
1388 nopt->hopopt = ip6_opt_dup(opt->hopopt, sk->sk_allocation);
1389 if (opt->hopopt && !nopt->hopopt)
1384 v6_cork->opt->hopopt = ip6_opt_dup(opt->hopopt,
1385 sk->sk_allocation);
1386 if (opt->hopopt && !v6_cork->opt->hopopt)
1390 return -ENOBUFS;
1391
1387 return -ENOBUFS;
1388
1392 nopt->srcrt = ip6_rthdr_dup(opt->srcrt, sk->sk_allocation);
1393 if (opt->srcrt && !nopt->srcrt)
1389 v6_cork->opt->srcrt = ip6_rthdr_dup(opt->srcrt,
1390 sk->sk_allocation);
1391 if (opt->srcrt && !v6_cork->opt->srcrt)
1394 return -ENOBUFS;
1395
1396 /* need source address above miyazawa*/
1397 }
1392 return -ENOBUFS;
1393
1394 /* need source address above miyazawa*/
1395 }
1396 dst_hold(&rt->dst);
1397 cork->base.dst = &rt->dst;
1398 cork->fl.u.ip6 = *fl6;
1398 v6_cork->hop_limit = ipc6->hlimit;
1399 v6_cork->tclass = ipc6->tclass;
1400 if (rt->dst.flags & DST_XFRM_TUNNEL)
1401 mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1402 READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst);
1403 else
1404 mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1405 READ_ONCE(rt->dst.dev->mtu) : dst_mtu(xfrm_dst_path(&rt->dst));

--- 12 unchanged lines hidden (view full) ---

1418 cork->base.length = 0;
1419
1420 cork->base.transmit_time = ipc6->sockc.transmit_time;
1421
1422 return 0;
1423}
1424
1425static int __ip6_append_data(struct sock *sk,
1399 v6_cork->hop_limit = ipc6->hlimit;
1400 v6_cork->tclass = ipc6->tclass;
1401 if (rt->dst.flags & DST_XFRM_TUNNEL)
1402 mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1403 READ_ONCE(rt->dst.dev->mtu) : dst_mtu(&rt->dst);
1404 else
1405 mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1406 READ_ONCE(rt->dst.dev->mtu) : dst_mtu(xfrm_dst_path(&rt->dst));

--- 12 unchanged lines hidden (view full) ---

1419 cork->base.length = 0;
1420
1421 cork->base.transmit_time = ipc6->sockc.transmit_time;
1422
1423 return 0;
1424}
1425
1426static int __ip6_append_data(struct sock *sk,
1427 struct flowi6 *fl6,
1426 struct sk_buff_head *queue,
1428 struct sk_buff_head *queue,
1427 struct inet_cork_full *cork_full,
1429 struct inet_cork *cork,
1428 struct inet6_cork *v6_cork,
1429 struct page_frag *pfrag,
1430 int getfrag(void *from, char *to, int offset,
1431 int len, int odd, struct sk_buff *skb),
1432 void *from, int length, int transhdrlen,
1433 unsigned int flags, struct ipcm6_cookie *ipc6)
1434{
1435 struct sk_buff *skb, *skb_prev = NULL;
1430 struct inet6_cork *v6_cork,
1431 struct page_frag *pfrag,
1432 int getfrag(void *from, char *to, int offset,
1433 int len, int odd, struct sk_buff *skb),
1434 void *from, int length, int transhdrlen,
1435 unsigned int flags, struct ipcm6_cookie *ipc6)
1436{
1437 struct sk_buff *skb, *skb_prev = NULL;
1436 struct inet_cork *cork = &cork_full->base;
1437 struct flowi6 *fl6 = &cork_full->fl.u.ip6;
1438 unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu;
1439 struct ubuf_info *uarg = NULL;
1440 int exthdrlen = 0;
1441 int dst_exthdrlen = 0;
1442 int hh_len;
1443 int copy;
1444 int err;
1445 int offset = 0;

--- 25 unchanged lines hidden (view full) ---

1471 (opt ? opt->opt_nflen : 0);
1472
1473 headersize = sizeof(struct ipv6hdr) +
1474 (opt ? opt->opt_flen + opt->opt_nflen : 0) +
1475 (dst_allfrag(&rt->dst) ?
1476 sizeof(struct frag_hdr) : 0) +
1477 rt->rt6i_nfheader_len;
1478
1438 unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu, pmtu;
1439 struct ubuf_info *uarg = NULL;
1440 int exthdrlen = 0;
1441 int dst_exthdrlen = 0;
1442 int hh_len;
1443 int copy;
1444 int err;
1445 int offset = 0;

--- 25 unchanged lines hidden (view full) ---

1471 (opt ? opt->opt_nflen : 0);
1472
1473 headersize = sizeof(struct ipv6hdr) +
1474 (opt ? opt->opt_flen + opt->opt_nflen : 0) +
1475 (dst_allfrag(&rt->dst) ?
1476 sizeof(struct frag_hdr) : 0) +
1477 rt->rt6i_nfheader_len;
1478
1479 if (mtu < fragheaderlen ||
1480 ((mtu - fragheaderlen) & ~7) + fragheaderlen < sizeof(struct frag_hdr))
1479 if (mtu <= fragheaderlen ||
1480 ((mtu - fragheaderlen) & ~7) + fragheaderlen <= sizeof(struct frag_hdr))
1481 goto emsgsize;
1482
1483 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
1484 sizeof(struct frag_hdr);
1485
1486 /* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit
1487 * the first fragment
1488 */
1489 if (headersize + transhdrlen > mtu)
1490 goto emsgsize;
1491
1492 if (cork->length + length > mtu - headersize && ipc6->dontfrag &&
1493 (sk->sk_protocol == IPPROTO_UDP ||
1481 goto emsgsize;
1482
1483 maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
1484 sizeof(struct frag_hdr);
1485
1486 /* as per RFC 7112 section 5, the entire IPv6 Header Chain must fit
1487 * the first fragment
1488 */
1489 if (headersize + transhdrlen > mtu)
1490 goto emsgsize;
1491
1492 if (cork->length + length > mtu - headersize && ipc6->dontfrag &&
1493 (sk->sk_protocol == IPPROTO_UDP ||
1494 sk->sk_protocol == IPPROTO_ICMPV6 ||
1495 sk->sk_protocol == IPPROTO_RAW)) {
1496 ipv6_local_rxpmtu(sk, fl6, mtu - headersize +
1497 sizeof(struct ipv6hdr));
1498 goto emsgsize;
1499 }
1500
1501 if (ip6_sk_ignore_df(sk))
1502 maxnonfragsize = sizeof(struct ipv6hdr) + IPV6_MAXPLEN;

--- 284 unchanged lines hidden (view full) ---

1787 int err;
1788
1789 if (flags&MSG_PROBE)
1790 return 0;
1791 if (skb_queue_empty(&sk->sk_write_queue)) {
1792 /*
1793 * setup for corking
1794 */
1494 sk->sk_protocol == IPPROTO_RAW)) {
1495 ipv6_local_rxpmtu(sk, fl6, mtu - headersize +
1496 sizeof(struct ipv6hdr));
1497 goto emsgsize;
1498 }
1499
1500 if (ip6_sk_ignore_df(sk))
1501 maxnonfragsize = sizeof(struct ipv6hdr) + IPV6_MAXPLEN;

--- 284 unchanged lines hidden (view full) ---

1786 int err;
1787
1788 if (flags&MSG_PROBE)
1789 return 0;
1790 if (skb_queue_empty(&sk->sk_write_queue)) {
1791 /*
1792 * setup for corking
1793 */
1795 dst_hold(&rt->dst);
1796 err = ip6_setup_cork(sk, &inet->cork, &np->cork,
1794 err = ip6_setup_cork(sk, &inet->cork, &np->cork,
1797 ipc6, rt);
1795 ipc6, rt, fl6);
1798 if (err)
1799 return err;
1800
1796 if (err)
1797 return err;
1798
1801 inet->cork.fl.u.ip6 = *fl6;
1802 exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0);
1803 length += exthdrlen;
1804 transhdrlen += exthdrlen;
1805 } else {
1799 exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0);
1800 length += exthdrlen;
1801 transhdrlen += exthdrlen;
1802 } else {
1803 fl6 = &inet->cork.fl.u.ip6;
1806 transhdrlen = 0;
1807 }
1808
1804 transhdrlen = 0;
1805 }
1806
1809 return __ip6_append_data(sk, &sk->sk_write_queue, &inet->cork,
1807 return __ip6_append_data(sk, fl6, &sk->sk_write_queue, &inet->cork.base,
1810 &np->cork, sk_page_frag(sk), getfrag,
1811 from, length, transhdrlen, flags, ipc6);
1812}
1813EXPORT_SYMBOL_GPL(ip6_append_data);
1814
1808 &np->cork, sk_page_frag(sk), getfrag,
1809 from, length, transhdrlen, flags, ipc6);
1810}
1811EXPORT_SYMBOL_GPL(ip6_append_data);
1812
1815static void ip6_cork_steal_dst(struct sk_buff *skb, struct inet_cork_full *cork)
1816{
1817 struct dst_entry *dst = cork->base.dst;
1818
1819 cork->base.dst = NULL;
1820 cork->base.flags &= ~IPCORK_ALLFRAG;
1821 skb_dst_set(skb, dst);
1822}
1823
1824static void ip6_cork_release(struct inet_cork_full *cork,
1825 struct inet6_cork *v6_cork)
1826{
1827 if (v6_cork->opt) {
1813static void ip6_cork_release(struct inet_cork_full *cork,
1814 struct inet6_cork *v6_cork)
1815{
1816 if (v6_cork->opt) {
1828 struct ipv6_txoptions *opt = v6_cork->opt;
1829
1830 kfree(opt->dst0opt);
1831 kfree(opt->dst1opt);
1832 kfree(opt->hopopt);
1833 kfree(opt->srcrt);
1834 kfree(opt);
1817 kfree(v6_cork->opt->dst0opt);
1818 kfree(v6_cork->opt->dst1opt);
1819 kfree(v6_cork->opt->hopopt);
1820 kfree(v6_cork->opt->srcrt);
1821 kfree(v6_cork->opt);
1835 v6_cork->opt = NULL;
1836 }
1837
1838 if (cork->base.dst) {
1839 dst_release(cork->base.dst);
1840 cork->base.dst = NULL;
1841 cork->base.flags &= ~IPCORK_ALLFRAG;
1842 }
1822 v6_cork->opt = NULL;
1823 }
1824
1825 if (cork->base.dst) {
1826 dst_release(cork->base.dst);
1827 cork->base.dst = NULL;
1828 cork->base.flags &= ~IPCORK_ALLFRAG;
1829 }
1830 memset(&cork->fl, 0, sizeof(cork->fl));
1843}
1844
1845struct sk_buff *__ip6_make_skb(struct sock *sk,
1846 struct sk_buff_head *queue,
1847 struct inet_cork_full *cork,
1848 struct inet6_cork *v6_cork)
1849{
1850 struct sk_buff *skb, *tmp_skb;
1851 struct sk_buff **tail_skb;
1831}
1832
1833struct sk_buff *__ip6_make_skb(struct sock *sk,
1834 struct sk_buff_head *queue,
1835 struct inet_cork_full *cork,
1836 struct inet6_cork *v6_cork)
1837{
1838 struct sk_buff *skb, *tmp_skb;
1839 struct sk_buff **tail_skb;
1852 struct in6_addr *final_dst;
1840 struct in6_addr final_dst_buf, *final_dst = &final_dst_buf;
1853 struct ipv6_pinfo *np = inet6_sk(sk);
1854 struct net *net = sock_net(sk);
1855 struct ipv6hdr *hdr;
1856 struct ipv6_txoptions *opt = v6_cork->opt;
1857 struct rt6_info *rt = (struct rt6_info *)cork->base.dst;
1858 struct flowi6 *fl6 = &cork->fl.u.ip6;
1859 unsigned char proto = fl6->flowi6_proto;
1860

--- 13 unchanged lines hidden (view full) ---

1874 skb->data_len += tmp_skb->len;
1875 skb->truesize += tmp_skb->truesize;
1876 tmp_skb->destructor = NULL;
1877 tmp_skb->sk = NULL;
1878 }
1879
1880 /* Allow local fragmentation. */
1881 skb->ignore_df = ip6_sk_ignore_df(sk);
1841 struct ipv6_pinfo *np = inet6_sk(sk);
1842 struct net *net = sock_net(sk);
1843 struct ipv6hdr *hdr;
1844 struct ipv6_txoptions *opt = v6_cork->opt;
1845 struct rt6_info *rt = (struct rt6_info *)cork->base.dst;
1846 struct flowi6 *fl6 = &cork->fl.u.ip6;
1847 unsigned char proto = fl6->flowi6_proto;
1848

--- 13 unchanged lines hidden (view full) ---

1862 skb->data_len += tmp_skb->len;
1863 skb->truesize += tmp_skb->truesize;
1864 tmp_skb->destructor = NULL;
1865 tmp_skb->sk = NULL;
1866 }
1867
1868 /* Allow local fragmentation. */
1869 skb->ignore_df = ip6_sk_ignore_df(sk);
1882 __skb_pull(skb, skb_network_header_len(skb));
1883
1870
1884 final_dst = &fl6->daddr;
1871 *final_dst = fl6->daddr;
1872 __skb_pull(skb, skb_network_header_len(skb));
1885 if (opt && opt->opt_flen)
1886 ipv6_push_frag_opts(skb, opt, &proto);
1887 if (opt && opt->opt_nflen)
1888 ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst, &fl6->saddr);
1889
1890 skb_push(skb, sizeof(struct ipv6hdr));
1891 skb_reset_network_header(skb);
1892 hdr = ipv6_hdr(skb);
1893
1894 ip6_flow_hdr(hdr, v6_cork->tclass,
1895 ip6_make_flowlabel(net, skb, fl6->flowlabel,
1896 ip6_autoflowlabel(net, np), fl6));
1897 hdr->hop_limit = v6_cork->hop_limit;
1898 hdr->nexthdr = proto;
1899 hdr->saddr = fl6->saddr;
1900 hdr->daddr = *final_dst;
1901
1902 skb->priority = sk->sk_priority;
1903 skb->mark = cork->base.mark;
1873 if (opt && opt->opt_flen)
1874 ipv6_push_frag_opts(skb, opt, &proto);
1875 if (opt && opt->opt_nflen)
1876 ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst, &fl6->saddr);
1877
1878 skb_push(skb, sizeof(struct ipv6hdr));
1879 skb_reset_network_header(skb);
1880 hdr = ipv6_hdr(skb);
1881
1882 ip6_flow_hdr(hdr, v6_cork->tclass,
1883 ip6_make_flowlabel(net, skb, fl6->flowlabel,
1884 ip6_autoflowlabel(net, np), fl6));
1885 hdr->hop_limit = v6_cork->hop_limit;
1886 hdr->nexthdr = proto;
1887 hdr->saddr = fl6->saddr;
1888 hdr->daddr = *final_dst;
1889
1890 skb->priority = sk->sk_priority;
1891 skb->mark = cork->base.mark;
1892
1904 skb->tstamp = cork->base.transmit_time;
1905
1893 skb->tstamp = cork->base.transmit_time;
1894
1906 ip6_cork_steal_dst(skb, cork);
1895 skb_dst_set(skb, dst_clone(&rt->dst));
1907 IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
1908 if (proto == IPPROTO_ICMPV6) {
1909 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
1910
1911 ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type);
1912 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
1913 }
1914

--- 55 unchanged lines hidden (view full) ---

1970 &inet_sk(sk)->cork, &inet6_sk(sk)->cork);
1971}
1972EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);
1973
1974struct sk_buff *ip6_make_skb(struct sock *sk,
1975 int getfrag(void *from, char *to, int offset,
1976 int len, int odd, struct sk_buff *skb),
1977 void *from, int length, int transhdrlen,
1896 IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
1897 if (proto == IPPROTO_ICMPV6) {
1898 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
1899
1900 ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type);
1901 ICMP6_INC_STATS(net, idev, ICMP6_MIB_OUTMSGS);
1902 }
1903

--- 55 unchanged lines hidden (view full) ---

1959 &inet_sk(sk)->cork, &inet6_sk(sk)->cork);
1960}
1961EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);
1962
1963struct sk_buff *ip6_make_skb(struct sock *sk,
1964 int getfrag(void *from, char *to, int offset,
1965 int len, int odd, struct sk_buff *skb),
1966 void *from, int length, int transhdrlen,
1978 struct ipcm6_cookie *ipc6, struct rt6_info *rt,
1979 unsigned int flags, struct inet_cork_full *cork)
1967 struct ipcm6_cookie *ipc6, struct flowi6 *fl6,
1968 struct rt6_info *rt, unsigned int flags,
1969 struct inet_cork_full *cork)
1980{
1981 struct inet6_cork v6_cork;
1982 struct sk_buff_head queue;
1983 int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0);
1984 int err;
1985
1970{
1971 struct inet6_cork v6_cork;
1972 struct sk_buff_head queue;
1973 int exthdrlen = (ipc6->opt ? ipc6->opt->opt_flen : 0);
1974 int err;
1975
1986 if (flags & MSG_PROBE) {
1987 dst_release(&rt->dst);
1976 if (flags & MSG_PROBE)
1988 return NULL;
1977 return NULL;
1989 }
1990
1991 __skb_queue_head_init(&queue);
1992
1993 cork->base.flags = 0;
1994 cork->base.addr = 0;
1995 cork->base.opt = NULL;
1978
1979 __skb_queue_head_init(&queue);
1980
1981 cork->base.flags = 0;
1982 cork->base.addr = 0;
1983 cork->base.opt = NULL;
1984 cork->base.dst = NULL;
1996 v6_cork.opt = NULL;
1985 v6_cork.opt = NULL;
1997 err = ip6_setup_cork(sk, cork, &v6_cork, ipc6, rt);
1986 err = ip6_setup_cork(sk, cork, &v6_cork, ipc6, rt, fl6);
1998 if (err) {
1999 ip6_cork_release(cork, &v6_cork);
2000 return ERR_PTR(err);
2001 }
2002 if (ipc6->dontfrag < 0)
2003 ipc6->dontfrag = inet6_sk(sk)->dontfrag;
2004
1987 if (err) {
1988 ip6_cork_release(cork, &v6_cork);
1989 return ERR_PTR(err);
1990 }
1991 if (ipc6->dontfrag < 0)
1992 ipc6->dontfrag = inet6_sk(sk)->dontfrag;
1993
2005 err = __ip6_append_data(sk, &queue, cork, &v6_cork,
1994 err = __ip6_append_data(sk, fl6, &queue, &cork->base, &v6_cork,
2006 &current->task_frag, getfrag, from,
2007 length + exthdrlen, transhdrlen + exthdrlen,
2008 flags, ipc6);
2009 if (err) {
2010 __ip6_flush_pending_frames(sk, &queue, cork, &v6_cork);
2011 return ERR_PTR(err);
2012 }
2013
2014 return __ip6_make_skb(sk, &queue, cork, &v6_cork);
2015}
1995 &current->task_frag, getfrag, from,
1996 length + exthdrlen, transhdrlen + exthdrlen,
1997 flags, ipc6);
1998 if (err) {
1999 __ip6_flush_pending_frames(sk, &queue, cork, &v6_cork);
2000 return ERR_PTR(err);
2001 }
2002
2003 return __ip6_make_skb(sk, &queue, cork, &v6_cork);
2004}