Branch data Line data Source code
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
9 : : *
10 : : * This program is free software; you can redistribute it and/or
11 : : * modify it under the terms of the GNU General Public License
12 : : * as published by the Free Software Foundation; either version
13 : : * 2 of the License, or (at your option) any later version.
14 : : *
15 : : * Changes:
16 : : * A.N.Kuznetsov : airthmetics in fragmentation.
17 : : * extension headers are implemented.
18 : : * route changes now work.
19 : : * ip6_forward does not confuse sniffers.
20 : : * etc.
21 : : *
22 : : * H. von Brand : Added missing #include <linux/string.h>
23 : : * Imran Patel : frag id should be in NBO
24 : : * Kazunori MIYAZAWA @USAGI
25 : : * : add ip6_append_data and related functions
26 : : * for datagram xmit
27 : : */
28 : :
29 : : #include <linux/errno.h>
30 : : #include <linux/kernel.h>
31 : : #include <linux/string.h>
32 : : #include <linux/socket.h>
33 : : #include <linux/net.h>
34 : : #include <linux/netdevice.h>
35 : : #include <linux/if_arp.h>
36 : : #include <linux/in6.h>
37 : : #include <linux/tcp.h>
38 : : #include <linux/route.h>
39 : : #include <linux/module.h>
40 : : #include <linux/slab.h>
41 : :
42 : : #include <linux/netfilter.h>
43 : : #include <linux/netfilter_ipv6.h>
44 : :
45 : : #include <net/sock.h>
46 : : #include <net/snmp.h>
47 : :
48 : : #include <net/ipv6.h>
49 : : #include <net/ndisc.h>
50 : : #include <net/protocol.h>
51 : : #include <net/ip6_route.h>
52 : : #include <net/addrconf.h>
53 : : #include <net/rawv6.h>
54 : : #include <net/icmp.h>
55 : : #include <net/xfrm.h>
56 : : #include <net/checksum.h>
57 : : #include <linux/mroute6.h>
58 : :
59 : 0 : static int ip6_finish_output2(struct sk_buff *skb)
60 : : {
61 : : struct dst_entry *dst = skb_dst(skb);
62 : 0 : struct net_device *dev = dst->dev;
63 : : struct neighbour *neigh;
64 : : struct in6_addr *nexthop;
65 : : int ret;
66 : :
67 : 0 : skb->protocol = htons(ETH_P_IPV6);
68 : 0 : skb->dev = dev;
69 : :
70 [ # # ]: 0 : if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
71 : : struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
72 : :
73 [ # # ][ # # ]: 0 : if (!(dev->flags & IFF_LOOPBACK) && sk_mc_loop(skb->sk) &&
74 : : ((mroute6_socket(dev_net(dev), skb) &&
75 [ # # ]: 0 : !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) ||
76 : 0 : ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr,
77 : 0 : &ipv6_hdr(skb)->saddr))) {
78 : 0 : struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC);
79 : :
80 : : /* Do not check for IFF_ALLMULTI; multicast routing
81 : : is not supported in any case.
82 : : */
83 [ # # ]: 0 : if (newskb)
84 : 0 : NF_HOOK(NFPROTO_IPV6, NF_INET_POST_ROUTING,
85 : : newskb, NULL, newskb->dev,
86 : : dev_loopback_xmit);
87 : :
88 [ # # ]: 0 : if (ipv6_hdr(skb)->hop_limit == 0) {
89 [ # # ]: 0 : IP6_INC_STATS(dev_net(dev), idev,
90 : : IPSTATS_MIB_OUTDISCARDS);
91 : 0 : kfree_skb(skb);
92 : 0 : return 0;
93 : : }
94 : : }
95 : :
96 [ # # ]: 0 : IP6_UPD_PO_STATS(dev_net(dev), idev, IPSTATS_MIB_OUTMCAST,
97 : : skb->len);
98 : :
99 [ # # ]: 0 : if (IPV6_ADDR_MC_SCOPE(&ipv6_hdr(skb)->daddr) <=
100 [ # # ]: 0 : IPV6_ADDR_SCOPE_NODELOCAL &&
101 : 0 : !(dev->flags & IFF_LOOPBACK)) {
102 : 0 : kfree_skb(skb);
103 : 0 : return 0;
104 : : }
105 : : }
106 : :
107 : : rcu_read_lock_bh();
108 : 0 : nexthop = rt6_nexthop((struct rt6_info *)dst);
109 : 0 : neigh = __ipv6_neigh_lookup_noref(dst->dev, nexthop);
110 [ # # ]: 0 : if (unlikely(!neigh))
111 : 0 : neigh = __neigh_create(&nd_tbl, nexthop, dst->dev, false);
112 [ # # ]: 0 : if (!IS_ERR(neigh)) {
113 : : ret = dst_neigh_output(dst, neigh, skb);
114 : : rcu_read_unlock_bh();
115 : 0 : return ret;
116 : : }
117 : : rcu_read_unlock_bh();
118 : :
119 [ # # ]: 0 : IP6_INC_STATS(dev_net(dst->dev),
120 : : ip6_dst_idev(dst), IPSTATS_MIB_OUTNOROUTES);
121 : 0 : kfree_skb(skb);
122 : 0 : return -EINVAL;
123 : : }
124 : :
125 : 0 : static int ip6_finish_output(struct sk_buff *skb)
126 : : {
127 [ # # ][ # # ]: 0 : if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) ||
[ # # ]
128 [ # # ]: 0 : dst_allfrag(skb_dst(skb)) ||
129 [ # # ]: 0 : (IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size))
130 : 0 : return ip6_fragment(skb, ip6_finish_output2);
131 : : else
132 : 0 : return ip6_finish_output2(skb);
133 : : }
134 : :
135 : 0 : int ip6_output(struct sk_buff *skb)
136 : : {
137 : 0 : struct net_device *dev = skb_dst(skb)->dev;
138 : : struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
139 [ # # ]: 0 : if (unlikely(idev->cnf.disable_ipv6)) {
140 [ # # ]: 0 : IP6_INC_STATS(dev_net(dev), idev,
141 : : IPSTATS_MIB_OUTDISCARDS);
142 : 0 : kfree_skb(skb);
143 : 0 : return 0;
144 : : }
145 : :
146 : 0 : return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, skb, NULL, dev,
147 : : ip6_finish_output,
148 : 0 : !(IP6CB(skb)->flags & IP6SKB_REROUTED));
149 : : }
150 : :
151 : : /*
152 : : * xmit an sk_buff (used by TCP, SCTP and DCCP)
153 : : */
154 : :
155 : 0 : int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6,
156 : : struct ipv6_txoptions *opt, int tclass)
157 : : {
158 : : struct net *net = sock_net(sk);
159 : : struct ipv6_pinfo *np = inet6_sk(sk);
160 : 0 : struct in6_addr *first_hop = &fl6->daddr;
161 : : struct dst_entry *dst = skb_dst(skb);
162 : : struct ipv6hdr *hdr;
163 : 0 : u8 proto = fl6->flowi6_proto;
164 : 0 : int seg_len = skb->len;
165 : : int hlimit = -1;
166 : : u32 mtu;
167 : :
168 [ # # ]: 0 : if (opt) {
169 : : unsigned int head_room;
170 : :
171 : : /* First: exthdrs may take lots of space (~8K for now)
172 : : MAX_HEADER is not enough.
173 : : */
174 : 0 : head_room = opt->opt_nflen + opt->opt_flen;
175 : 0 : seg_len += head_room;
176 : 0 : head_room += sizeof(struct ipv6hdr) + LL_RESERVED_SPACE(dst->dev);
177 : :
178 [ # # ]: 0 : if (skb_headroom(skb) < head_room) {
179 : 0 : struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room);
180 [ # # ]: 0 : if (skb2 == NULL) {
181 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
182 : : IPSTATS_MIB_OUTDISCARDS);
183 : 0 : kfree_skb(skb);
184 : 0 : return -ENOBUFS;
185 : : }
186 : 0 : consume_skb(skb);
187 : : skb = skb2;
188 : : skb_set_owner_w(skb, sk);
189 : : }
190 [ # # ]: 0 : if (opt->opt_flen)
191 : 0 : ipv6_push_frag_opts(skb, opt, &proto);
192 [ # # ]: 0 : if (opt->opt_nflen)
193 : 0 : ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop);
194 : : }
195 : :
196 : 0 : skb_push(skb, sizeof(struct ipv6hdr));
197 : : skb_reset_network_header(skb);
198 : : hdr = ipv6_hdr(skb);
199 : :
200 : : /*
201 : : * Fill in the IPv6 header
202 : : */
203 [ # # ]: 0 : if (np)
204 : 0 : hlimit = np->hop_limit;
205 [ # # ]: 0 : if (hlimit < 0)
206 : 0 : hlimit = ip6_dst_hoplimit(dst);
207 : :
208 : 0 : ip6_flow_hdr(hdr, tclass, fl6->flowlabel);
209 : :
210 [ # # ]: 0 : hdr->payload_len = htons(seg_len);
211 : 0 : hdr->nexthdr = proto;
212 : 0 : hdr->hop_limit = hlimit;
213 : :
214 : 0 : hdr->saddr = fl6->saddr;
215 : 0 : hdr->daddr = *first_hop;
216 : :
217 : 0 : skb->protocol = htons(ETH_P_IPV6);
218 : 0 : skb->priority = sk->sk_priority;
219 : 0 : skb->mark = sk->sk_mark;
220 : :
221 : : mtu = dst_mtu(dst);
222 [ # # ][ # # ]: 0 : if ((skb->len <= mtu) || skb->local_df || skb_is_gso(skb)) {
[ # # ]
223 [ # # ]: 0 : IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)),
224 : : IPSTATS_MIB_OUT, skb->len);
225 : 0 : return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, skb, NULL,
226 : : dst->dev, dst_output);
227 : : }
228 : :
229 : 0 : skb->dev = dst->dev;
230 : 0 : ipv6_local_error(sk, EMSGSIZE, fl6, mtu);
231 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS);
232 : 0 : kfree_skb(skb);
233 : 0 : return -EMSGSIZE;
234 : : }
235 : :
236 : : EXPORT_SYMBOL(ip6_xmit);
237 : :
238 : 0 : static int ip6_call_ra_chain(struct sk_buff *skb, int sel)
239 : : {
240 : : struct ip6_ra_chain *ra;
241 : : struct sock *last = NULL;
242 : :
243 : 0 : read_lock(&ip6_ra_lock);
244 [ # # ]: 0 : for (ra = ip6_ra_chain; ra; ra = ra->next) {
245 : 0 : struct sock *sk = ra->sk;
246 [ # # ][ # # ]: 0 : if (sk && ra->sel == sel &&
[ # # ]
247 [ # # ]: 0 : (!sk->sk_bound_dev_if ||
248 : 0 : sk->sk_bound_dev_if == skb->dev->ifindex)) {
249 [ # # ]: 0 : if (last) {
250 : 0 : struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
251 [ # # ]: 0 : if (skb2)
252 : 0 : rawv6_rcv(last, skb2);
253 : : }
254 : : last = sk;
255 : : }
256 : : }
257 : :
258 [ # # ]: 0 : if (last) {
259 : 0 : rawv6_rcv(last, skb);
260 : : read_unlock(&ip6_ra_lock);
261 : 0 : return 1;
262 : : }
263 : : read_unlock(&ip6_ra_lock);
264 : 0 : return 0;
265 : : }
266 : :
267 : 0 : static int ip6_forward_proxy_check(struct sk_buff *skb)
268 : : {
269 : : struct ipv6hdr *hdr = ipv6_hdr(skb);
270 : 0 : u8 nexthdr = hdr->nexthdr;
271 : : __be16 frag_off;
272 : : int offset;
273 : :
274 [ # # ]: 0 : if (ipv6_ext_hdr(nexthdr)) {
275 : 0 : offset = ipv6_skip_exthdr(skb, sizeof(*hdr), &nexthdr, &frag_off);
276 [ # # ]: 0 : if (offset < 0)
277 : : return 0;
278 : : } else
279 : : offset = sizeof(struct ipv6hdr);
280 : :
281 [ # # ]: 0 : if (nexthdr == IPPROTO_ICMPV6) {
282 : : struct icmp6hdr *icmp6;
283 : :
284 [ # # ]: 0 : if (!pskb_may_pull(skb, (skb_network_header(skb) +
285 : 0 : offset + 1 - skb->data)))
286 : : return 0;
287 : :
288 : 0 : icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset);
289 : :
290 [ # # ]: 0 : switch (icmp6->icmp6_type) {
291 : : case NDISC_ROUTER_SOLICITATION:
292 : : case NDISC_ROUTER_ADVERTISEMENT:
293 : : case NDISC_NEIGHBOUR_SOLICITATION:
294 : : case NDISC_NEIGHBOUR_ADVERTISEMENT:
295 : : case NDISC_REDIRECT:
296 : : /* For reaction involving unicast neighbor discovery
297 : : * message destined to the proxied address, pass it to
298 : : * input function.
299 : : */
300 : : return 1;
301 : : default:
302 : : break;
303 : : }
304 : : }
305 : :
306 : : /*
307 : : * The proxying router can't forward traffic sent to a link-local
308 : : * address, so signal the sender and discard the packet. This
309 : : * behavior is clarified by the MIPv6 specification.
310 : : */
311 [ # # ]: 0 : if (ipv6_addr_type(&hdr->daddr) & IPV6_ADDR_LINKLOCAL) {
312 : : dst_link_failure(skb);
313 : : return -1;
314 : : }
315 : :
316 : : return 0;
317 : : }
318 : :
319 : 0 : static inline int ip6_forward_finish(struct sk_buff *skb)
320 : : {
321 : 0 : return dst_output(skb);
322 : : }
323 : :
324 : : static unsigned int ip6_dst_mtu_forward(const struct dst_entry *dst)
325 : : {
326 : : unsigned int mtu;
327 : : struct inet6_dev *idev;
328 : :
329 [ # # ]: 0 : if (dst_metric_locked(dst, RTAX_MTU)) {
330 : : mtu = dst_metric_raw(dst, RTAX_MTU);
331 [ # # ]: 0 : if (mtu)
332 : : return mtu;
333 : : }
334 : :
335 : : mtu = IPV6_MIN_MTU;
336 : : rcu_read_lock();
337 : 0 : idev = __in6_dev_get(dst->dev);
338 [ # # ]: 0 : if (idev)
339 : 0 : mtu = idev->cnf.mtu6;
340 : : rcu_read_unlock();
341 : :
342 : : return mtu;
343 : : }
344 : :
345 : 0 : static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu)
346 : : {
347 [ # # ][ # # ]: 0 : if (skb->len <= mtu || skb->local_df)
348 : : return false;
349 : :
350 [ # # ][ # # ]: 0 : if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu)
351 : : return true;
352 : :
353 [ # # # # ]: 0 : if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu)
354 : : return false;
355 : :
356 : : return true;
357 : : }
358 : :
359 : 0 : int ip6_forward(struct sk_buff *skb)
360 : : {
361 : : struct dst_entry *dst = skb_dst(skb);
362 : : struct ipv6hdr *hdr = ipv6_hdr(skb);
363 : : struct inet6_skb_parm *opt = IP6CB(skb);
364 : : struct net *net = dev_net(dst->dev);
365 : : u32 mtu;
366 : :
367 [ # # ]: 0 : if (net->ipv6.devconf_all->forwarding == 0)
368 : : goto error;
369 : :
370 [ # # ]: 0 : if (skb_warn_if_lro(skb))
371 : : goto drop;
372 : :
373 [ # # ]: 0 : if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) {
374 [ # # ]: 0 : IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
375 : : IPSTATS_MIB_INDISCARDS);
376 : : goto drop;
377 : : }
378 : :
379 [ # # ]: 0 : if (skb->pkt_type != PACKET_HOST)
380 : : goto drop;
381 : :
382 : : skb_forward_csum(skb);
383 : :
384 : : /*
385 : : * We DO NOT make any processing on
386 : : * RA packets, pushing them to user level AS IS
387 : : * without ane WARRANTY that application will be able
388 : : * to interpret them. The reason is that we
389 : : * cannot make anything clever here.
390 : : *
391 : : * We are not end-node, so that if packet contains
392 : : * AH/ESP, we cannot make anything.
393 : : * Defragmentation also would be mistake, RA packets
394 : : * cannot be fragmented, because there is no warranty
395 : : * that different fragments will go along one path. --ANK
396 : : */
397 [ # # ]: 0 : if (unlikely(opt->flags & IP6SKB_ROUTERALERT)) {
398 [ # # ][ # # ]: 0 : if (ip6_call_ra_chain(skb, ntohs(opt->ra)))
399 : : return 0;
400 : : }
401 : :
402 : : /*
403 : : * check and decrement ttl
404 : : */
405 [ # # ]: 0 : if (hdr->hop_limit <= 1) {
406 : : /* Force OUTPUT device used as source address */
407 : 0 : skb->dev = dst->dev;
408 : 0 : icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0);
409 [ # # ]: 0 : IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
410 : : IPSTATS_MIB_INHDRERRORS);
411 : :
412 : 0 : kfree_skb(skb);
413 : 0 : return -ETIMEDOUT;
414 : : }
415 : :
416 : : /* XXX: idev->cnf.proxy_ndp? */
417 [ # # # # ]: 0 : if (net->ipv6.devconf_all->proxy_ndp &&
418 : 0 : pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) {
419 : 0 : int proxied = ip6_forward_proxy_check(skb);
420 [ # # ]: 0 : if (proxied > 0)
421 : 0 : return ip6_input(skb);
422 [ # # ]: 0 : else if (proxied < 0) {
423 [ # # ]: 0 : IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
424 : : IPSTATS_MIB_INDISCARDS);
425 : : goto drop;
426 : : }
427 : : }
428 : :
429 [ # # ]: 0 : if (!xfrm6_route_forward(skb)) {
430 [ # # ]: 0 : IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
431 : : IPSTATS_MIB_INDISCARDS);
432 : : goto drop;
433 : : }
434 : : dst = skb_dst(skb);
435 : :
436 : : /* IPv6 specs say nothing about it, but it is clear that we cannot
437 : : send redirects to source routed frames.
438 : : We don't send redirects to frames decapsulated from IPsec.
439 : : */
440 [ # # ][ # # ]: 0 : if (skb->dev == dst->dev && opt->srcrt == 0 && !skb_sec_path(skb)) {
[ # # ]
441 : : struct in6_addr *target = NULL;
442 : : struct inet_peer *peer;
443 : : struct rt6_info *rt;
444 : :
445 : : /*
446 : : * incoming and outgoing devices are the same
447 : : * send a redirect.
448 : : */
449 : :
450 : : rt = (struct rt6_info *) dst;
451 [ # # ]: 0 : if (rt->rt6i_flags & RTF_GATEWAY)
452 : 0 : target = &rt->rt6i_gateway;
453 : : else
454 : 0 : target = &hdr->daddr;
455 : :
456 : 0 : peer = inet_getpeer_v6(net->ipv6.peers, &rt->rt6i_dst.addr, 1);
457 : :
458 : : /* Limit redirects both by destination (here)
459 : : and by source (inside ndisc_send_redirect)
460 : : */
461 [ # # ]: 0 : if (inet_peer_xrlim_allow(peer, 1*HZ))
462 : 0 : ndisc_send_redirect(skb, target);
463 [ # # ]: 0 : if (peer)
464 : 0 : inet_putpeer(peer);
465 : : } else {
466 : 0 : int addrtype = ipv6_addr_type(&hdr->saddr);
467 : :
468 : : /* This check is security critical. */
469 [ # # ][ # # ]: 0 : if (addrtype == IPV6_ADDR_ANY ||
470 : 0 : addrtype & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LOOPBACK))
471 : : goto error;
472 [ # # ]: 0 : if (addrtype & IPV6_ADDR_LINKLOCAL) {
473 : 0 : icmpv6_send(skb, ICMPV6_DEST_UNREACH,
474 : : ICMPV6_NOT_NEIGHBOUR, 0);
475 : 0 : goto error;
476 : : }
477 : : }
478 : :
479 : : mtu = ip6_dst_mtu_forward(dst);
480 [ # # ]: 0 : if (mtu < IPV6_MIN_MTU)
481 : : mtu = IPV6_MIN_MTU;
482 : :
483 [ # # ]: 0 : if (ip6_pkt_too_big(skb, mtu)) {
484 : : /* Again, force OUTPUT device used as source address */
485 : 0 : skb->dev = dst->dev;
486 : 0 : icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
487 [ # # ]: 0 : IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
488 : : IPSTATS_MIB_INTOOBIGERRORS);
489 [ # # ]: 0 : IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
490 : : IPSTATS_MIB_FRAGFAILS);
491 : 0 : kfree_skb(skb);
492 : 0 : return -EMSGSIZE;
493 : : }
494 : :
495 [ # # ]: 0 : if (skb_cow(skb, dst->dev->hard_header_len)) {
496 [ # # ]: 0 : IP6_INC_STATS_BH(net, ip6_dst_idev(dst),
497 : : IPSTATS_MIB_OUTDISCARDS);
498 : : goto drop;
499 : : }
500 : :
501 : : hdr = ipv6_hdr(skb);
502 : :
503 : : /* Mangling hops number delayed to point after skb COW */
504 : :
505 : 0 : hdr->hop_limit--;
506 : :
507 [ # # ]: 0 : IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTFORWDATAGRAMS);
508 [ # # ]: 0 : IP6_ADD_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTOCTETS, skb->len);
509 : 0 : return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, skb, skb->dev, dst->dev,
510 : : ip6_forward_finish);
511 : :
512 : : error:
513 [ # # ]: 0 : IP6_INC_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_INADDRERRORS);
514 : : drop:
515 : 0 : kfree_skb(skb);
516 : 0 : return -EINVAL;
517 : : }
518 : :
519 : 0 : static void ip6_copy_metadata(struct sk_buff *to, struct sk_buff *from)
520 : : {
521 : 0 : to->pkt_type = from->pkt_type;
522 : 0 : to->priority = from->priority;
523 : 0 : to->protocol = from->protocol;
524 : : skb_dst_drop(to);
525 : : skb_dst_set(to, dst_clone(skb_dst(from)));
526 : 0 : to->dev = from->dev;
527 : 0 : to->mark = from->mark;
528 : :
529 : : #ifdef CONFIG_NET_SCHED
530 : : to->tc_index = from->tc_index;
531 : : #endif
532 : : nf_copy(to, from);
533 : : skb_copy_secmark(to, from);
534 : 0 : }
535 : :
536 : 0 : int ip6_fragment(struct sk_buff *skb, int (*output)(struct sk_buff *))
537 : : {
538 : 0 : struct sk_buff *frag;
539 : : struct rt6_info *rt = (struct rt6_info*)skb_dst(skb);
540 [ # # ]: 0 : struct ipv6_pinfo *np = skb->sk ? inet6_sk(skb->sk) : NULL;
541 : : struct ipv6hdr *tmp_hdr;
542 : : struct frag_hdr *fh;
543 : : unsigned int mtu, hlen, left, len;
544 : : int hroom, troom;
545 : : __be32 frag_id = 0;
546 : : int ptr, offset = 0, err=0;
547 : : u8 *prevhdr, nexthdr = 0;
548 : : struct net *net = dev_net(skb_dst(skb)->dev);
549 : :
550 : 0 : hlen = ip6_find_1stfragopt(skb, &prevhdr);
551 : 0 : nexthdr = *prevhdr;
552 : :
553 : 0 : mtu = ip6_skb_dst_mtu(skb);
554 : :
555 : : /* We must not fragment if the socket is set to force MTU discovery
556 : : * or if the skb it not generated by a local socket.
557 : : */
558 [ # # ][ # # ]: 0 : if (unlikely(!skb->local_df && skb->len > mtu) ||
[ # # ]
559 [ # # ]: 0 : (IP6CB(skb)->frag_max_size &&
560 : 0 : IP6CB(skb)->frag_max_size > mtu)) {
561 [ # # ][ # # ]: 0 : if (skb->sk && dst_allfrag(skb_dst(skb)))
562 : : sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK);
563 : :
564 : 0 : skb->dev = skb_dst(skb)->dev;
565 : 0 : icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
566 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
567 : : IPSTATS_MIB_FRAGFAILS);
568 : 0 : kfree_skb(skb);
569 : 0 : return -EMSGSIZE;
570 : : }
571 : :
572 [ # # ][ # # ]: 0 : if (np && np->frag_size < mtu) {
573 [ # # ]: 0 : if (np->frag_size)
574 : : mtu = np->frag_size;
575 : : }
576 : 0 : mtu -= hlen + sizeof(struct frag_hdr);
577 : :
578 [ # # ]: 0 : if (skb_has_frag_list(skb)) {
579 : : int first_len = skb_pagelen(skb);
580 : : struct sk_buff *frag2;
581 : :
582 [ # # ][ # # ]: 0 : if (first_len - hlen > mtu ||
583 [ # # ]: 0 : ((first_len - hlen) & 7) ||
584 : : skb_cloned(skb))
585 : : goto slow_path;
586 : :
587 [ # # ]: 0 : skb_walk_frags(skb, frag) {
588 : : /* Correct geometry. */
589 [ # # ][ # # ]: 0 : if (frag->len > mtu ||
590 [ # # ][ # # ]: 0 : ((frag->len & 7) && frag->next) ||
591 : : skb_headroom(frag) < hlen)
592 : : goto slow_path_clean;
593 : :
594 : : /* Partially cloned skb? */
595 [ # # ]: 0 : if (skb_shared(frag))
596 : : goto slow_path_clean;
597 : :
598 [ # # ]: 0 : BUG_ON(frag->sk);
599 [ # # ]: 0 : if (skb->sk) {
600 : 0 : frag->sk = skb->sk;
601 : 0 : frag->destructor = sock_wfree;
602 : : }
603 : 0 : skb->truesize -= frag->truesize;
604 : : }
605 : :
606 : : err = 0;
607 : : offset = 0;
608 : 0 : frag = skb_shinfo(skb)->frag_list;
609 : : skb_frag_list_init(skb);
610 : : /* BUILD HEADER */
611 : :
612 : 0 : *prevhdr = NEXTHDR_FRAGMENT;
613 : 0 : tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC);
614 [ # # ]: 0 : if (!tmp_hdr) {
615 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
616 : : IPSTATS_MIB_FRAGFAILS);
617 : 0 : return -ENOMEM;
618 : : }
619 : :
620 : : __skb_pull(skb, hlen);
621 : 0 : fh = (struct frag_hdr*)__skb_push(skb, sizeof(struct frag_hdr));
622 : : __skb_push(skb, hlen);
623 : : skb_reset_network_header(skb);
624 : 0 : memcpy(skb_network_header(skb), tmp_hdr, hlen);
625 : :
626 : 0 : ipv6_select_ident(fh, rt);
627 : 0 : fh->nexthdr = nexthdr;
628 : 0 : fh->reserved = 0;
629 : 0 : fh->frag_off = htons(IP6_MF);
630 : 0 : frag_id = fh->identification;
631 : :
632 : : first_len = skb_pagelen(skb);
633 : 0 : skb->data_len = first_len - skb_headlen(skb);
634 : 0 : skb->len = first_len;
635 [ # # ]: 0 : ipv6_hdr(skb)->payload_len = htons(first_len -
636 : : sizeof(struct ipv6hdr));
637 : :
638 : : dst_hold(&rt->dst);
639 : :
640 : : for (;;) {
641 : : /* Prepare header of the next frame,
642 : : * before previous one went down. */
643 [ # # ]: 0 : if (frag) {
644 : 0 : frag->ip_summed = CHECKSUM_NONE;
645 : : skb_reset_transport_header(frag);
646 : : fh = (struct frag_hdr*)__skb_push(frag, sizeof(struct frag_hdr));
647 : : __skb_push(frag, hlen);
648 : : skb_reset_network_header(frag);
649 : 0 : memcpy(skb_network_header(frag), tmp_hdr,
650 : : hlen);
651 : 0 : offset += skb->len - hlen - sizeof(struct frag_hdr);
652 : 0 : fh->nexthdr = nexthdr;
653 : 0 : fh->reserved = 0;
654 [ # # ]: 0 : fh->frag_off = htons(offset);
655 [ # # ]: 0 : if (frag->next != NULL)
656 : 0 : fh->frag_off |= htons(IP6_MF);
657 : 0 : fh->identification = frag_id;
658 : 0 : ipv6_hdr(frag)->payload_len =
659 [ # # ]: 0 : htons(frag->len -
660 : : sizeof(struct ipv6hdr));
661 : 0 : ip6_copy_metadata(frag, skb);
662 : : }
663 : :
664 : 0 : err = output(skb);
665 [ # # ]: 0 : if(!err)
666 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
667 : : IPSTATS_MIB_FRAGCREATES);
668 : :
669 [ # # ]: 0 : if (err || !frag)
670 : : break;
671 : :
672 : : skb = frag;
673 : 0 : frag = skb->next;
674 : 0 : skb->next = NULL;
675 : 0 : }
676 : :
677 : 0 : kfree(tmp_hdr);
678 : :
679 [ # # ]: 0 : if (err == 0) {
680 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
681 : : IPSTATS_MIB_FRAGOKS);
682 : : ip6_rt_put(rt);
683 : 0 : return 0;
684 : : }
685 : :
686 [ # # ]: 0 : while (frag) {
687 : 0 : skb = frag->next;
688 : 0 : kfree_skb(frag);
689 : : frag = skb;
690 : : }
691 : :
692 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(&rt->dst),
693 : : IPSTATS_MIB_FRAGFAILS);
694 : : ip6_rt_put(rt);
695 : 0 : return err;
696 : :
697 : : slow_path_clean:
698 [ # # ]: 0 : skb_walk_frags(skb, frag2) {
699 [ # # ]: 0 : if (frag2 == frag)
700 : : break;
701 : 0 : frag2->sk = NULL;
702 : 0 : frag2->destructor = NULL;
703 : 0 : skb->truesize += frag2->truesize;
704 : : }
705 : : }
706 : :
707 : : slow_path:
708 [ # # # # ]: 0 : if ((skb->ip_summed == CHECKSUM_PARTIAL) &&
709 : 0 : skb_checksum_help(skb))
710 : : goto fail;
711 : :
712 : 0 : left = skb->len - hlen; /* Space per frame */
713 : : ptr = hlen; /* Where to start from */
714 : :
715 : : /*
716 : : * Fragment the datagram.
717 : : */
718 : :
719 : 0 : *prevhdr = NEXTHDR_FRAGMENT;
720 : 0 : hroom = LL_RESERVED_SPACE(rt->dst.dev);
721 : 0 : troom = rt->dst.dev->needed_tailroom;
722 : :
723 : : /*
724 : : * Keep copying data until we run out.
725 : : */
726 [ # # ]: 0 : while(left > 0) {
727 : : len = left;
728 : : /* IF: it doesn't fit, use 'mtu' - the data space left */
729 [ # # ]: 0 : if (len > mtu)
730 : : len = mtu;
731 : : /* IF: we are not sending up to and including the packet end
732 : : then align the next start on an eight byte boundary */
733 [ # # ]: 0 : if (len < left) {
734 : 0 : len &= ~7;
735 : : }
736 : : /*
737 : : * Allocate buffer.
738 : : */
739 : :
740 [ # # ]: 0 : if ((frag = alloc_skb(len + hlen + sizeof(struct frag_hdr) +
741 : 0 : hroom + troom, GFP_ATOMIC)) == NULL) {
742 [ # # ]: 0 : NETDEBUG(KERN_INFO "IPv6: frag: no memory for new fragment!\n");
743 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
744 : : IPSTATS_MIB_FRAGFAILS);
745 : : err = -ENOMEM;
746 : 0 : goto fail;
747 : : }
748 : :
749 : : /*
750 : : * Set up data on packet
751 : : */
752 : :
753 : 0 : ip6_copy_metadata(frag, skb);
754 : : skb_reserve(frag, hroom);
755 : 0 : skb_put(frag, len + hlen + sizeof(struct frag_hdr));
756 : : skb_reset_network_header(frag);
757 : 0 : fh = (struct frag_hdr *)(skb_network_header(frag) + hlen);
758 : 0 : frag->transport_header = (frag->network_header + hlen +
759 : : sizeof(struct frag_hdr));
760 : :
761 : : /*
762 : : * Charge the memory for the fragment to any owner
763 : : * it might possess
764 : : */
765 [ # # ]: 0 : if (skb->sk)
766 : : skb_set_owner_w(frag, skb->sk);
767 : :
768 : : /*
769 : : * Copy the packet header into the new buffer.
770 : : */
771 : : skb_copy_from_linear_data(skb, skb_network_header(frag), hlen);
772 : :
773 : : /*
774 : : * Build fragment header.
775 : : */
776 : 0 : fh->nexthdr = nexthdr;
777 : 0 : fh->reserved = 0;
778 [ # # ]: 0 : if (!frag_id) {
779 : 0 : ipv6_select_ident(fh, rt);
780 : 0 : frag_id = fh->identification;
781 : : } else
782 : 0 : fh->identification = frag_id;
783 : :
784 : : /*
785 : : * Copy a block of the IP datagram.
786 : : */
787 [ # # ]: 0 : if (skb_copy_bits(skb, ptr, skb_transport_header(frag), len))
788 : 0 : BUG();
789 : 0 : left -= len;
790 : :
791 [ # # ]: 0 : fh->frag_off = htons(offset);
792 [ # # ]: 0 : if (left > 0)
793 : 0 : fh->frag_off |= htons(IP6_MF);
794 [ # # ]: 0 : ipv6_hdr(frag)->payload_len = htons(frag->len -
795 : : sizeof(struct ipv6hdr));
796 : :
797 : 0 : ptr += len;
798 : 0 : offset += len;
799 : :
800 : : /*
801 : : * Put this fragment into the sending queue.
802 : : */
803 : 0 : err = output(frag);
804 [ # # ]: 0 : if (err)
805 : : goto fail;
806 : :
807 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
808 : : IPSTATS_MIB_FRAGCREATES);
809 : : }
810 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
811 : : IPSTATS_MIB_FRAGOKS);
812 : 0 : consume_skb(skb);
813 : 0 : return err;
814 : :
815 : : fail:
816 [ # # ]: 0 : IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
817 : : IPSTATS_MIB_FRAGFAILS);
818 : 0 : kfree_skb(skb);
819 : 0 : return err;
820 : : }
821 : :
822 : : static inline int ip6_rt_check(const struct rt6key *rt_key,
823 : : const struct in6_addr *fl_addr,
824 : : const struct in6_addr *addr_cache)
825 : : {
826 [ # # ][ # # ]: 0 : return (rt_key->plen != 128 || !ipv6_addr_equal(fl_addr, &rt_key->addr)) &&
[ # # ]
827 [ # # ]: 0 : (addr_cache == NULL || !ipv6_addr_equal(fl_addr, addr_cache));
828 : : }
829 : :
830 : 0 : static struct dst_entry *ip6_sk_dst_check(struct sock *sk,
831 : : struct dst_entry *dst,
832 : : const struct flowi6 *fl6)
833 : : {
834 : : struct ipv6_pinfo *np = inet6_sk(sk);
835 : : struct rt6_info *rt;
836 : :
837 [ # # ]: 0 : if (!dst)
838 : : goto out;
839 : :
840 [ # # ]: 0 : if (dst->ops->family != AF_INET6) {
841 : 0 : dst_release(dst);
842 : 0 : return NULL;
843 : : }
844 : :
845 : : rt = (struct rt6_info *)dst;
846 : : /* Yes, checking route validity in not connected
847 : : * case is not very simple. Take into account,
848 : : * that we do not support routing by source, TOS,
849 : : * and MSG_DONTROUTE --ANK (980726)
850 : : *
851 : : * 1. ip6_rt_check(): If route was host route,
852 : : * check that cached destination is current.
853 : : * If it is network route, we still may
854 : : * check its validity using saved pointer
855 : : * to the last used address: daddr_cache.
856 : : * We do not want to save whole address now,
857 : : * (because main consumer of this service
858 : : * is tcp, which has not this problem),
859 : : * so that the last trick works only on connected
860 : : * sockets.
861 : : * 2. oif also should be the same.
862 : : */
863 [ # # ][ # # ]: 0 : if (ip6_rt_check(&rt->rt6i_dst, &fl6->daddr, np->daddr_cache) ||
864 : : #ifdef CONFIG_IPV6_SUBTREES
865 : : ip6_rt_check(&rt->rt6i_src, &fl6->saddr, np->saddr_cache) ||
866 : : #endif
867 [ # # ]: 0 : (fl6->flowi6_oif && fl6->flowi6_oif != dst->dev->ifindex)) {
868 : 0 : dst_release(dst);
869 : : dst = NULL;
870 : : }
871 : :
872 : : out:
873 : 0 : return dst;
874 : : }
875 : :
876 : 0 : static int ip6_dst_lookup_tail(struct sock *sk,
877 : : struct dst_entry **dst, struct flowi6 *fl6)
878 : : {
879 : : struct net *net = sock_net(sk);
880 : : #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
881 : : struct neighbour *n;
882 : : struct rt6_info *rt;
883 : : #endif
884 : : int err;
885 : :
886 [ # # ]: 0 : if (*dst == NULL)
887 : 0 : *dst = ip6_route_output(net, sk, fl6);
888 : :
889 [ # # ]: 0 : if ((err = (*dst)->error))
890 : : goto out_err_release;
891 : :
892 [ # # ]: 0 : if (ipv6_addr_any(&fl6->saddr)) {
893 : : struct rt6_info *rt = (struct rt6_info *) *dst;
894 [ # # ]: 0 : err = ip6_route_get_saddr(net, rt, &fl6->daddr,
895 : 0 : sk ? inet6_sk(sk)->srcprefs : 0,
896 : : &fl6->saddr);
897 [ # # ]: 0 : if (err)
898 : : goto out_err_release;
899 : : }
900 : :
901 : : #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
902 : : /*
903 : : * Here if the dst entry we've looked up
904 : : * has a neighbour entry that is in the INCOMPLETE
905 : : * state and the src address from the flow is
906 : : * marked as OPTIMISTIC, we release the found
907 : : * dst entry and replace it instead with the
908 : : * dst entry of the nexthop router
909 : : */
910 : : rt = (struct rt6_info *) *dst;
911 : : rcu_read_lock_bh();
912 : : n = __ipv6_neigh_lookup_noref(rt->dst.dev, rt6_nexthop(rt));
913 : : err = n && !(n->nud_state & NUD_VALID) ? -EINVAL : 0;
914 : : rcu_read_unlock_bh();
915 : :
916 : : if (err) {
917 : : struct inet6_ifaddr *ifp;
918 : : struct flowi6 fl_gw6;
919 : : int redirect;
920 : :
921 : : ifp = ipv6_get_ifaddr(net, &fl6->saddr,
922 : : (*dst)->dev, 1);
923 : :
924 : : redirect = (ifp && ifp->flags & IFA_F_OPTIMISTIC);
925 : : if (ifp)
926 : : in6_ifa_put(ifp);
927 : :
928 : : if (redirect) {
929 : : /*
930 : : * We need to get the dst entry for the
931 : : * default router instead
932 : : */
933 : : dst_release(*dst);
934 : : memcpy(&fl_gw6, fl6, sizeof(struct flowi6));
935 : : memset(&fl_gw6.daddr, 0, sizeof(struct in6_addr));
936 : : *dst = ip6_route_output(net, sk, &fl_gw6);
937 : : if ((err = (*dst)->error))
938 : : goto out_err_release;
939 : : }
940 : : }
941 : : #endif
942 : :
943 : : return 0;
944 : :
945 : : out_err_release:
946 [ # # ]: 0 : if (err == -ENETUNREACH)
947 : 0 : IP6_INC_STATS(net, NULL, IPSTATS_MIB_OUTNOROUTES);
948 : 0 : dst_release(*dst);
949 : 0 : *dst = NULL;
950 : 0 : return err;
951 : : }
952 : :
953 : : /**
954 : : * ip6_dst_lookup - perform route lookup on flow
955 : : * @sk: socket which provides route info
956 : : * @dst: pointer to dst_entry * for result
957 : : * @fl6: flow to lookup
958 : : *
959 : : * This function performs a route lookup on the given flow.
960 : : *
961 : : * It returns zero on success, or a standard errno code on error.
962 : : */
963 : 0 : int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi6 *fl6)
964 : : {
965 : 0 : *dst = NULL;
966 : 0 : return ip6_dst_lookup_tail(sk, dst, fl6);
967 : : }
968 : : EXPORT_SYMBOL_GPL(ip6_dst_lookup);
969 : :
970 : : /**
971 : : * ip6_dst_lookup_flow - perform route lookup on flow with ipsec
972 : : * @sk: socket which provides route info
973 : : * @fl6: flow to lookup
974 : : * @final_dst: final destination address for ipsec lookup
975 : : *
976 : : * This function performs a route lookup on the given flow.
977 : : *
978 : : * It returns a valid dst pointer on success, or a pointer encoded
979 : : * error code.
980 : : */
981 : 0 : struct dst_entry *ip6_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
982 : : const struct in6_addr *final_dst)
983 : : {
984 : 0 : struct dst_entry *dst = NULL;
985 : : int err;
986 : :
987 : 0 : err = ip6_dst_lookup_tail(sk, &dst, fl6);
988 [ # # ]: 0 : if (err)
989 : 0 : return ERR_PTR(err);
990 [ # # ]: 0 : if (final_dst)
991 : 0 : fl6->daddr = *final_dst;
992 : :
993 : 0 : return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
994 : : }
995 : : EXPORT_SYMBOL_GPL(ip6_dst_lookup_flow);
996 : :
997 : : /**
998 : : * ip6_sk_dst_lookup_flow - perform socket cached route lookup on flow
999 : : * @sk: socket which provides the dst cache and route info
1000 : : * @fl6: flow to lookup
1001 : : * @final_dst: final destination address for ipsec lookup
1002 : : *
1003 : : * This function performs a route lookup on the given flow with the
1004 : : * possibility of using the cached route in the socket if it is valid.
1005 : : * It will take the socket dst lock when operating on the dst cache.
1006 : : * As a result, this function can only be used in process context.
1007 : : *
1008 : : * It returns a valid dst pointer on success, or a pointer encoded
1009 : : * error code.
1010 : : */
1011 : 0 : struct dst_entry *ip6_sk_dst_lookup_flow(struct sock *sk, struct flowi6 *fl6,
1012 : : const struct in6_addr *final_dst)
1013 : : {
1014 : 0 : struct dst_entry *dst = sk_dst_check(sk, inet6_sk(sk)->dst_cookie);
1015 : : int err;
1016 : :
1017 : 0 : dst = ip6_sk_dst_check(sk, dst, fl6);
1018 : :
1019 : 0 : err = ip6_dst_lookup_tail(sk, &dst, fl6);
1020 [ # # ]: 0 : if (err)
1021 : 0 : return ERR_PTR(err);
1022 [ # # ]: 0 : if (final_dst)
1023 : 0 : fl6->daddr = *final_dst;
1024 : :
1025 : 0 : return xfrm_lookup(sock_net(sk), dst, flowi6_to_flowi(fl6), sk, 0);
1026 : : }
1027 : : EXPORT_SYMBOL_GPL(ip6_sk_dst_lookup_flow);
1028 : :
1029 : : static inline int ip6_ufo_append_data(struct sock *sk,
1030 : : int getfrag(void *from, char *to, int offset, int len,
1031 : : int odd, struct sk_buff *skb),
1032 : : void *from, int length, int hh_len, int fragheaderlen,
1033 : : int transhdrlen, int mtu,unsigned int flags,
1034 : : struct rt6_info *rt)
1035 : :
1036 : : {
1037 : 0 : struct sk_buff *skb;
1038 : : struct frag_hdr fhdr;
1039 : : int err;
1040 : :
1041 : : /* There is support for UDP large send offload by network
1042 : : * device, so create one single skb packet containing complete
1043 : : * udp datagram
1044 : : */
1045 [ # # ]: 0 : if ((skb = skb_peek_tail(&sk->sk_write_queue)) == NULL) {
1046 : 0 : skb = sock_alloc_send_skb(sk,
1047 : 0 : hh_len + fragheaderlen + transhdrlen + 20,
1048 : : (flags & MSG_DONTWAIT), &err);
1049 [ # # ]: 0 : if (skb == NULL)
1050 : 0 : return err;
1051 : :
1052 : : /* reserve space for Hardware header */
1053 : : skb_reserve(skb, hh_len);
1054 : :
1055 : : /* create space for UDP/IP header */
1056 : 0 : skb_put(skb,fragheaderlen + transhdrlen);
1057 : :
1058 : : /* initialize network header pointer */
1059 : : skb_reset_network_header(skb);
1060 : :
1061 : : /* initialize protocol header pointer */
1062 : 0 : skb->transport_header = skb->network_header + fragheaderlen;
1063 : :
1064 : 0 : skb->protocol = htons(ETH_P_IPV6);
1065 : 0 : skb->csum = 0;
1066 : :
1067 : : __skb_queue_tail(&sk->sk_write_queue, skb);
1068 [ # # ]: 0 : } else if (skb_is_gso(skb)) {
1069 : : goto append;
1070 : : }
1071 : :
1072 : 0 : skb->ip_summed = CHECKSUM_PARTIAL;
1073 : : /* Specify the length of each IPv6 datagram fragment.
1074 : : * It has to be a multiple of 8.
1075 : : */
1076 : 0 : skb_shinfo(skb)->gso_size = (mtu - fragheaderlen -
1077 : : sizeof(struct frag_hdr)) & ~7;
1078 : 0 : skb_shinfo(skb)->gso_type = SKB_GSO_UDP;
1079 : 0 : ipv6_select_ident(&fhdr, rt);
1080 : 0 : skb_shinfo(skb)->ip6_frag_id = fhdr.identification;
1081 : :
1082 : : append:
1083 : 0 : return skb_append_datato_frags(sk, skb, getfrag, from,
1084 : : (length - transhdrlen));
1085 : : }
1086 : :
1087 : : static inline struct ipv6_opt_hdr *ip6_opt_dup(struct ipv6_opt_hdr *src,
1088 : : gfp_t gfp)
1089 : : {
1090 [ # # ][ # # ]: 0 : return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL;
[ # # ]
1091 : : }
1092 : :
1093 : : static inline struct ipv6_rt_hdr *ip6_rthdr_dup(struct ipv6_rt_hdr *src,
1094 : : gfp_t gfp)
1095 : : {
1096 [ # # ]: 0 : return src ? kmemdup(src, (src->hdrlen + 1) * 8, gfp) : NULL;
1097 : : }
1098 : :
1099 : : static void ip6_append_data_mtu(unsigned int *mtu,
1100 : : int *maxfraglen,
1101 : : unsigned int fragheaderlen,
1102 : : struct sk_buff *skb,
1103 : : struct rt6_info *rt,
1104 : : unsigned int orig_mtu)
1105 : : {
1106 [ # # ]: 0 : if (!(rt->dst.flags & DST_XFRM_TUNNEL)) {
1107 [ # # ]: 0 : if (skb == NULL) {
1108 : : /* first fragment, reserve header_len */
1109 : 0 : *mtu = orig_mtu - rt->dst.header_len;
1110 : :
1111 : : } else {
1112 : : /*
1113 : : * this fragment is not first, the headers
1114 : : * space is regarded as data space.
1115 : : */
1116 : : *mtu = orig_mtu;
1117 : : }
1118 : 0 : *maxfraglen = ((*mtu - fragheaderlen) & ~7)
1119 : 0 : + fragheaderlen - sizeof(struct frag_hdr);
1120 : : }
1121 : : }
1122 : :
1123 : 0 : int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
1124 : : int offset, int len, int odd, struct sk_buff *skb),
1125 : : void *from, int length, int transhdrlen,
1126 : : int hlimit, int tclass, struct ipv6_txoptions *opt, struct flowi6 *fl6,
1127 : 0 : struct rt6_info *rt, unsigned int flags, int dontfrag)
1128 : : {
1129 : : struct inet_sock *inet = inet_sk(sk);
1130 : : struct ipv6_pinfo *np = inet6_sk(sk);
1131 : : struct inet_cork *cork;
1132 : 0 : struct sk_buff *skb, *skb_prev = NULL;
1133 : : unsigned int maxfraglen, fragheaderlen, mtu, orig_mtu;
1134 : : int exthdrlen;
1135 : : int dst_exthdrlen;
1136 : : int hh_len;
1137 : : int copy;
1138 : : int err;
1139 : : int offset = 0;
1140 : 0 : __u8 tx_flags = 0;
1141 : :
1142 [ # # ]: 0 : if (flags&MSG_PROBE)
1143 : : return 0;
1144 : : cork = &inet->cork.base;
1145 [ # # ]: 0 : if (skb_queue_empty(&sk->sk_write_queue)) {
1146 : : /*
1147 : : * setup for corking
1148 : : */
1149 [ # # ]: 0 : if (opt) {
1150 [ # # ][ # # ]: 0 : if (WARN_ON(np->cork.opt))
1151 : : return -EINVAL;
1152 : :
1153 : 0 : np->cork.opt = kzalloc(opt->tot_len, sk->sk_allocation);
1154 [ # # ]: 0 : if (unlikely(np->cork.opt == NULL))
1155 : : return -ENOBUFS;
1156 : :
1157 : 0 : np->cork.opt->tot_len = opt->tot_len;
1158 : 0 : np->cork.opt->opt_flen = opt->opt_flen;
1159 : 0 : np->cork.opt->opt_nflen = opt->opt_nflen;
1160 : :
1161 : 0 : np->cork.opt->dst0opt = ip6_opt_dup(opt->dst0opt,
1162 : : sk->sk_allocation);
1163 [ # # ][ # # ]: 0 : if (opt->dst0opt && !np->cork.opt->dst0opt)
1164 : : return -ENOBUFS;
1165 : :
1166 : 0 : np->cork.opt->dst1opt = ip6_opt_dup(opt->dst1opt,
1167 : : sk->sk_allocation);
1168 [ # # ][ # # ]: 0 : if (opt->dst1opt && !np->cork.opt->dst1opt)
1169 : : return -ENOBUFS;
1170 : :
1171 : 0 : np->cork.opt->hopopt = ip6_opt_dup(opt->hopopt,
1172 : : sk->sk_allocation);
1173 [ # # ][ # # ]: 0 : if (opt->hopopt && !np->cork.opt->hopopt)
1174 : : return -ENOBUFS;
1175 : :
1176 : 0 : np->cork.opt->srcrt = ip6_rthdr_dup(opt->srcrt,
1177 : : sk->sk_allocation);
1178 [ # # ][ # # ]: 0 : if (opt->srcrt && !np->cork.opt->srcrt)
1179 : : return -ENOBUFS;
1180 : :
1181 : : /* need source address above miyazawa*/
1182 : : }
1183 : : dst_hold(&rt->dst);
1184 : 0 : cork->dst = &rt->dst;
1185 : 0 : inet->cork.fl.u.ip6 = *fl6;
1186 : 0 : np->cork.hop_limit = hlimit;
1187 : 0 : np->cork.tclass = tclass;
1188 [ # # ]: 0 : if (rt->dst.flags & DST_XFRM_TUNNEL)
1189 : 0 : mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1190 [ # # ]: 0 : rt->dst.dev->mtu : dst_mtu(&rt->dst);
1191 : : else
1192 : 0 : mtu = np->pmtudisc >= IPV6_PMTUDISC_PROBE ?
1193 [ # # ]: 0 : rt->dst.dev->mtu : dst_mtu(rt->dst.path);
1194 [ # # ]: 0 : if (np->frag_size < mtu) {
1195 [ # # ]: 0 : if (np->frag_size)
1196 : : mtu = np->frag_size;
1197 : : }
1198 : 0 : cork->fragsize = mtu;
1199 [ # # ]: 0 : if (dst_allfrag(rt->dst.path))
1200 : 0 : cork->flags |= IPCORK_ALLFRAG;
1201 : 0 : cork->length = 0;
1202 [ # # ]: 0 : exthdrlen = (opt ? opt->opt_flen : 0);
1203 : 0 : length += exthdrlen;
1204 : 0 : transhdrlen += exthdrlen;
1205 : 0 : dst_exthdrlen = rt->dst.header_len - rt->rt6i_nfheader_len;
1206 : : } else {
1207 : 0 : rt = (struct rt6_info *)cork->dst;
1208 : 0 : fl6 = &inet->cork.fl.u.ip6;
1209 : 0 : opt = np->cork.opt;
1210 : : transhdrlen = 0;
1211 : : exthdrlen = 0;
1212 : : dst_exthdrlen = 0;
1213 : 0 : mtu = cork->fragsize;
1214 : : }
1215 : : orig_mtu = mtu;
1216 : :
1217 : 0 : hh_len = LL_RESERVED_SPACE(rt->dst.dev);
1218 : :
1219 [ # # ]: 0 : fragheaderlen = sizeof(struct ipv6hdr) + rt->rt6i_nfheader_len +
1220 : 0 : (opt ? opt->opt_nflen : 0);
1221 : 0 : maxfraglen = ((mtu - fragheaderlen) & ~7) + fragheaderlen -
1222 : : sizeof(struct frag_hdr);
1223 : :
1224 [ # # ]: 0 : if (mtu <= sizeof(struct ipv6hdr) + IPV6_MAXPLEN) {
1225 : : unsigned int maxnonfragsize, headersize;
1226 : :
1227 [ # # ]: 0 : headersize = sizeof(struct ipv6hdr) +
1228 : 0 : (opt ? opt->tot_len : 0) +
1229 : : (dst_allfrag(&rt->dst) ?
1230 [ # # ]: 0 : sizeof(struct frag_hdr) : 0) +
1231 : : rt->rt6i_nfheader_len;
1232 : :
1233 : 0 : maxnonfragsize = (np->pmtudisc >= IPV6_PMTUDISC_DO) ?
1234 [ # # ]: 0 : mtu : sizeof(struct ipv6hdr) + IPV6_MAXPLEN;
1235 : :
1236 : : /* dontfrag active */
1237 [ # # ][ # # ]: 0 : if ((cork->length + length > mtu - headersize) && dontfrag &&
[ # # ]
1238 : 0 : (sk->sk_protocol == IPPROTO_UDP ||
1239 : : sk->sk_protocol == IPPROTO_RAW)) {
1240 : 0 : ipv6_local_rxpmtu(sk, fl6, mtu - headersize +
1241 : : sizeof(struct ipv6hdr));
1242 : 0 : goto emsgsize;
1243 : : }
1244 : :
1245 [ # # ]: 0 : if (cork->length + length > maxnonfragsize - headersize) {
1246 : : emsgsize:
1247 : 0 : ipv6_local_error(sk, EMSGSIZE, fl6,
1248 : : mtu - headersize +
1249 : : sizeof(struct ipv6hdr));
1250 : 0 : return -EMSGSIZE;
1251 : : }
1252 : : }
1253 : :
1254 : : /* For UDP, check if TX timestamp is enabled */
1255 [ # # ]: 0 : if (sk->sk_type == SOCK_DGRAM)
1256 : 0 : sock_tx_timestamp(sk, &tx_flags);
1257 : :
1258 : : /*
1259 : : * Let's try using as much space as possible.
1260 : : * Use MTU if total length of the message fits into the MTU.
1261 : : * Otherwise, we need to reserve fragment header and
1262 : : * fragment alignment (= 8-15 octects, in total).
1263 : : *
1264 : : * Note that we may need to "move" the data from the tail of
1265 : : * of the buffer to the new fragment when we split
1266 : : * the message.
1267 : : *
1268 : : * FIXME: It may be fragmented into multiple chunks
1269 : : * at once if non-fragmentable extension headers
1270 : : * are too large.
1271 : : * --yoshfuji
1272 : : */
1273 : :
1274 : : skb = skb_peek_tail(&sk->sk_write_queue);
1275 : 0 : cork->length += length;
1276 [ # # ][ # # ]: 0 : if (((length > mtu) ||
1277 [ # # ][ # # ]: 0 : (skb && skb_is_gso(skb))) &&
1278 [ # # ]: 0 : (sk->sk_protocol == IPPROTO_UDP) &&
1279 : 0 : (rt->dst.dev->features & NETIF_F_UFO)) {
1280 : 0 : err = ip6_ufo_append_data(sk, getfrag, from, length,
1281 : : hh_len, fragheaderlen,
1282 : : transhdrlen, mtu, flags, rt);
1283 [ # # ]: 0 : if (err)
1284 : : goto error;
1285 : : return 0;
1286 : : }
1287 : :
1288 [ # # ]: 0 : if (!skb)
1289 : : goto alloc_new_skb;
1290 : :
1291 [ # # ]: 0 : while (length > 0) {
1292 : : /* Check if the remaining data fits into current packet. */
1293 [ # # ][ # # ]: 0 : copy = (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - skb->len;
1294 [ # # ]: 0 : if (copy < length)
1295 : 0 : copy = maxfraglen - skb->len;
1296 : :
1297 [ # # ]: 0 : if (copy <= 0) {
1298 : : char *data;
1299 : : unsigned int datalen;
1300 : : unsigned int fraglen;
1301 : : unsigned int fraggap;
1302 : : unsigned int alloclen;
1303 : : alloc_new_skb:
1304 : : /* There's no room in the current skb */
1305 [ # # ]: 0 : if (skb)
1306 : 0 : fraggap = skb->len - maxfraglen;
1307 : : else
1308 : : fraggap = 0;
1309 : : /* update mtu and maxfraglen if necessary */
1310 [ # # ]: 0 : if (skb == NULL || skb_prev == NULL)
1311 : : ip6_append_data_mtu(&mtu, &maxfraglen,
1312 : : fragheaderlen, skb, rt,
1313 : : orig_mtu);
1314 : :
1315 : : skb_prev = skb;
1316 : :
1317 : : /*
1318 : : * If remaining data exceeds the mtu,
1319 : : * we know we need more fragment(s).
1320 : : */
1321 : 0 : datalen = length + fraggap;
1322 : :
1323 [ # # ][ # # ]: 0 : if (datalen > (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - fragheaderlen)
[ # # ]
1324 : 0 : datalen = maxfraglen - fragheaderlen - rt->dst.trailer_len;
1325 [ # # ][ # # ]: 0 : if ((flags & MSG_MORE) &&
1326 : 0 : !(rt->dst.dev->features&NETIF_F_SG))
1327 : : alloclen = mtu;
1328 : : else
1329 : 0 : alloclen = datalen + fragheaderlen;
1330 : :
1331 : 0 : alloclen += dst_exthdrlen;
1332 : :
1333 [ # # ]: 0 : if (datalen != length + fraggap) {
1334 : : /*
1335 : : * this is not the last fragment, the trailer
1336 : : * space is regarded as data space.
1337 : : */
1338 : 0 : datalen += rt->dst.trailer_len;
1339 : : }
1340 : :
1341 : 0 : alloclen += rt->dst.trailer_len;
1342 : 0 : fraglen = datalen + fragheaderlen;
1343 : :
1344 : : /*
1345 : : * We just reserve space for fragment header.
1346 : : * Note: this may be overallocation if the message
1347 : : * (without MSG_MORE) fits into the MTU.
1348 : : */
1349 : 0 : alloclen += sizeof(struct frag_hdr);
1350 : :
1351 [ # # ]: 0 : if (transhdrlen) {
1352 : 0 : skb = sock_alloc_send_skb(sk,
1353 : 0 : alloclen + hh_len,
1354 : : (flags & MSG_DONTWAIT), &err);
1355 : : } else {
1356 : : skb = NULL;
1357 [ # # ]: 0 : if (atomic_read(&sk->sk_wmem_alloc) <=
1358 : 0 : 2 * sk->sk_sndbuf)
1359 : 0 : skb = sock_wmalloc(sk,
1360 : 0 : alloclen + hh_len, 1,
1361 : : sk->sk_allocation);
1362 [ # # ]: 0 : if (unlikely(skb == NULL))
1363 : 0 : err = -ENOBUFS;
1364 : : else {
1365 : : /* Only the initial fragment
1366 : : * is time stamped.
1367 : : */
1368 : 0 : tx_flags = 0;
1369 : : }
1370 : : }
1371 [ # # ]: 0 : if (skb == NULL)
1372 : : goto error;
1373 : : /*
1374 : : * Fill in the control structures
1375 : : */
1376 : 0 : skb->protocol = htons(ETH_P_IPV6);
1377 : 0 : skb->ip_summed = CHECKSUM_NONE;
1378 : 0 : skb->csum = 0;
1379 : : /* reserve for fragmentation and ipsec header */
1380 : 0 : skb_reserve(skb, hh_len + sizeof(struct frag_hdr) +
1381 : : dst_exthdrlen);
1382 : :
1383 [ # # ]: 0 : if (sk->sk_type == SOCK_DGRAM)
1384 : 0 : skb_shinfo(skb)->tx_flags = tx_flags;
1385 : :
1386 : : /*
1387 : : * Find where to start putting bytes
1388 : : */
1389 : 0 : data = skb_put(skb, fraglen);
1390 : : skb_set_network_header(skb, exthdrlen);
1391 : 0 : data += fragheaderlen;
1392 : 0 : skb->transport_header = (skb->network_header +
1393 : : fragheaderlen);
1394 [ # # ]: 0 : if (fraggap) {
1395 : 0 : skb->csum = skb_copy_and_csum_bits(
1396 : : skb_prev, maxfraglen,
1397 : : data + transhdrlen, fraggap, 0);
1398 : 0 : skb_prev->csum = csum_sub(skb_prev->csum,
1399 : : skb->csum);
1400 : 0 : data += fraggap;
1401 : : pskb_trim_unique(skb_prev, maxfraglen);
1402 : : }
1403 : 0 : copy = datalen - transhdrlen - fraggap;
1404 : :
1405 [ # # ]: 0 : if (copy < 0) {
1406 : 0 : err = -EINVAL;
1407 : 0 : kfree_skb(skb);
1408 : 0 : goto error;
1409 [ # # ][ # # ]: 0 : } else if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) {
1410 : 0 : err = -EFAULT;
1411 : 0 : kfree_skb(skb);
1412 : 0 : goto error;
1413 : : }
1414 : :
1415 : 0 : offset += copy;
1416 : 0 : length -= datalen - fraggap;
1417 : : transhdrlen = 0;
1418 : : exthdrlen = 0;
1419 : : dst_exthdrlen = 0;
1420 : :
1421 : : /*
1422 : : * Put the packet on the pending queue
1423 : : */
1424 : : __skb_queue_tail(&sk->sk_write_queue, skb);
1425 : 0 : continue;
1426 : : }
1427 : :
1428 [ # # ]: 0 : if (copy > length)
1429 : : copy = length;
1430 : :
1431 [ # # ]: 0 : if (!(rt->dst.dev->features&NETIF_F_SG)) {
1432 : : unsigned int off;
1433 : :
1434 : : off = skb->len;
1435 [ # # ]: 0 : if (getfrag(from, skb_put(skb, copy),
1436 : : offset, copy, off, skb) < 0) {
1437 : : __skb_trim(skb, off);
1438 : 0 : err = -EFAULT;
1439 : 0 : goto error;
1440 : : }
1441 : : } else {
1442 : 0 : int i = skb_shinfo(skb)->nr_frags;
1443 : : struct page_frag *pfrag = sk_page_frag(sk);
1444 : :
1445 : 0 : err = -ENOMEM;
1446 [ # # ]: 0 : if (!sk_page_frag_refill(sk, pfrag))
1447 : : goto error;
1448 : :
1449 [ # # ]: 0 : if (!skb_can_coalesce(skb, i, pfrag->page,
1450 : 0 : pfrag->offset)) {
1451 : 0 : err = -EMSGSIZE;
1452 [ # # ]: 0 : if (i == MAX_SKB_FRAGS)
1453 : : goto error;
1454 : :
1455 : 0 : __skb_fill_page_desc(skb, i, pfrag->page,
1456 : : pfrag->offset, 0);
1457 : 0 : skb_shinfo(skb)->nr_frags = ++i;
1458 : 0 : get_page(pfrag->page);
1459 : : }
1460 : 0 : copy = min_t(int, copy, pfrag->size - pfrag->offset);
1461 [ # # ]: 0 : if (getfrag(from,
1462 : 0 : page_address(pfrag->page) + pfrag->offset,
1463 : 0 : offset, copy, skb->len, skb) < 0)
1464 : : goto error_efault;
1465 : :
1466 : 0 : pfrag->offset += copy;
1467 : 0 : skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy);
1468 : 0 : skb->len += copy;
1469 : 0 : skb->data_len += copy;
1470 : 0 : skb->truesize += copy;
1471 : 0 : atomic_add(copy, &sk->sk_wmem_alloc);
1472 : : }
1473 : 0 : offset += copy;
1474 : 0 : length -= copy;
1475 : : }
1476 : :
1477 : : return 0;
1478 : :
1479 : : error_efault:
1480 : 0 : err = -EFAULT;
1481 : : error:
1482 : 0 : cork->length -= length;
1483 [ # # ]: 0 : IP6_INC_STATS(sock_net(sk), rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
1484 : 0 : return err;
1485 : : }
1486 : : EXPORT_SYMBOL_GPL(ip6_append_data);
1487 : :
1488 : 0 : static void ip6_cork_release(struct inet_sock *inet, struct ipv6_pinfo *np)
1489 : : {
1490 [ # # ]: 0 : if (np->cork.opt) {
1491 : 0 : kfree(np->cork.opt->dst0opt);
1492 : 0 : kfree(np->cork.opt->dst1opt);
1493 : 0 : kfree(np->cork.opt->hopopt);
1494 : 0 : kfree(np->cork.opt->srcrt);
1495 : 0 : kfree(np->cork.opt);
1496 : 0 : np->cork.opt = NULL;
1497 : : }
1498 : :
1499 [ # # ]: 0 : if (inet->cork.base.dst) {
1500 : 0 : dst_release(inet->cork.base.dst);
1501 : 0 : inet->cork.base.dst = NULL;
1502 : 0 : inet->cork.base.flags &= ~IPCORK_ALLFRAG;
1503 : : }
1504 : 0 : memset(&inet->cork.fl, 0, sizeof(inet->cork.fl));
1505 : 0 : }
1506 : :
1507 : 0 : int ip6_push_pending_frames(struct sock *sk)
1508 : : {
1509 : 0 : struct sk_buff *skb, *tmp_skb;
1510 : : struct sk_buff **tail_skb;
1511 : 0 : struct in6_addr final_dst_buf, *final_dst = &final_dst_buf;
1512 : : struct inet_sock *inet = inet_sk(sk);
1513 : : struct ipv6_pinfo *np = inet6_sk(sk);
1514 : : struct net *net = sock_net(sk);
1515 : : struct ipv6hdr *hdr;
1516 : 0 : struct ipv6_txoptions *opt = np->cork.opt;
1517 : 0 : struct rt6_info *rt = (struct rt6_info *)inet->cork.base.dst;
1518 : : struct flowi6 *fl6 = &inet->cork.fl.u.ip6;
1519 : 0 : unsigned char proto = fl6->flowi6_proto;
1520 : : int err = 0;
1521 : :
1522 [ # # ]: 0 : if ((skb = __skb_dequeue(&sk->sk_write_queue)) == NULL)
1523 : : goto out;
1524 : 0 : tail_skb = &(skb_shinfo(skb)->frag_list);
1525 : :
1526 : : /* move skb->data to ip header from ext header */
1527 [ # # ]: 0 : if (skb->data < skb_network_header(skb))
1528 : 0 : __skb_pull(skb, skb_network_offset(skb));
1529 [ # # ]: 0 : while ((tmp_skb = __skb_dequeue(&sk->sk_write_queue)) != NULL) {
1530 : : __skb_pull(tmp_skb, skb_network_header_len(skb));
1531 : 0 : *tail_skb = tmp_skb;
1532 : 0 : tail_skb = &(tmp_skb->next);
1533 : 0 : skb->len += tmp_skb->len;
1534 : 0 : skb->data_len += tmp_skb->len;
1535 : 0 : skb->truesize += tmp_skb->truesize;
1536 : 0 : tmp_skb->destructor = NULL;
1537 : 0 : tmp_skb->sk = NULL;
1538 : : }
1539 : :
1540 : : /* Allow local fragmentation. */
1541 [ # # ]: 0 : if (np->pmtudisc < IPV6_PMTUDISC_DO)
1542 : 0 : skb->local_df = 1;
1543 : :
1544 : 0 : *final_dst = fl6->daddr;
1545 : : __skb_pull(skb, skb_network_header_len(skb));
1546 [ # # ][ # # ]: 0 : if (opt && opt->opt_flen)
1547 : 0 : ipv6_push_frag_opts(skb, opt, &proto);
1548 [ # # ][ # # ]: 0 : if (opt && opt->opt_nflen)
1549 : 0 : ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst);
1550 : :
1551 : 0 : skb_push(skb, sizeof(struct ipv6hdr));
1552 : : skb_reset_network_header(skb);
1553 : : hdr = ipv6_hdr(skb);
1554 : :
1555 : 0 : ip6_flow_hdr(hdr, np->cork.tclass, fl6->flowlabel);
1556 : 0 : hdr->hop_limit = np->cork.hop_limit;
1557 : 0 : hdr->nexthdr = proto;
1558 : 0 : hdr->saddr = fl6->saddr;
1559 : 0 : hdr->daddr = *final_dst;
1560 : :
1561 : 0 : skb->priority = sk->sk_priority;
1562 : 0 : skb->mark = sk->sk_mark;
1563 : :
1564 : 0 : skb_dst_set(skb, dst_clone(&rt->dst));
1565 [ # # ]: 0 : IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len);
1566 [ # # ]: 0 : if (proto == IPPROTO_ICMPV6) {
1567 : : struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb));
1568 : :
1569 [ # # ]: 0 : ICMP6MSGOUT_INC_STATS_BH(net, idev, icmp6_hdr(skb)->icmp6_type);
1570 [ # # ]: 0 : ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS);
1571 : : }
1572 : :
1573 : 0 : err = ip6_local_out(skb);
1574 [ # # ]: 0 : if (err) {
1575 [ # # ]: 0 : if (err > 0)
1576 [ # # ]: 0 : err = net_xmit_errno(err);
1577 [ # # ]: 0 : if (err)
1578 : : goto error;
1579 : : }
1580 : :
1581 : : out:
1582 : 0 : ip6_cork_release(inet, np);
1583 : 0 : return err;
1584 : : error:
1585 [ # # ]: 0 : IP6_INC_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUTDISCARDS);
1586 : : goto out;
1587 : : }
1588 : : EXPORT_SYMBOL_GPL(ip6_push_pending_frames);
1589 : :
1590 : 0 : void ip6_flush_pending_frames(struct sock *sk)
1591 : : {
1592 : 0 : struct sk_buff *skb;
1593 : :
1594 [ # # ]: 0 : while ((skb = __skb_dequeue_tail(&sk->sk_write_queue)) != NULL) {
1595 [ # # ]: 0 : if (skb_dst(skb))
1596 [ # # ]: 0 : IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb_dst(skb)),
1597 : : IPSTATS_MIB_OUTDISCARDS);
1598 : 0 : kfree_skb(skb);
1599 : : }
1600 : :
1601 : 0 : ip6_cork_release(inet_sk(sk), inet6_sk(sk));
1602 : 0 : }
1603 : : EXPORT_SYMBOL_GPL(ip6_flush_pending_frames);
|