Lines Matching refs:skb
59 static int ip6_finish_output2(struct sock *sk, struct sk_buff *skb) in ip6_finish_output2() argument
61 struct dst_entry *dst = skb_dst(skb); in ip6_finish_output2()
67 skb->protocol = htons(ETH_P_IPV6); in ip6_finish_output2()
68 skb->dev = dev; in ip6_finish_output2()
70 if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) { in ip6_finish_output2()
71 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); in ip6_finish_output2()
74 ((mroute6_socket(dev_net(dev), skb) && in ip6_finish_output2()
75 !(IP6CB(skb)->flags & IP6SKB_FORWARDED)) || in ip6_finish_output2()
76 ipv6_chk_mcast_addr(dev, &ipv6_hdr(skb)->daddr, in ip6_finish_output2()
77 &ipv6_hdr(skb)->saddr))) { in ip6_finish_output2()
78 struct sk_buff *newskb = skb_clone(skb, GFP_ATOMIC); in ip6_finish_output2()
88 if (ipv6_hdr(skb)->hop_limit == 0) { in ip6_finish_output2()
91 kfree_skb(skb); in ip6_finish_output2()
97 skb->len); in ip6_finish_output2()
99 if (IPV6_ADDR_MC_SCOPE(&ipv6_hdr(skb)->daddr) <= in ip6_finish_output2()
102 kfree_skb(skb); in ip6_finish_output2()
113 ret = dst_neigh_output(dst, neigh, skb); in ip6_finish_output2()
121 kfree_skb(skb); in ip6_finish_output2()
125 static int ip6_finish_output(struct sock *sk, struct sk_buff *skb) in ip6_finish_output() argument
127 if ((skb->len > ip6_skb_dst_mtu(skb) && !skb_is_gso(skb)) || in ip6_finish_output()
128 dst_allfrag(skb_dst(skb)) || in ip6_finish_output()
129 (IP6CB(skb)->frag_max_size && skb->len > IP6CB(skb)->frag_max_size)) in ip6_finish_output()
130 return ip6_fragment(sk, skb, ip6_finish_output2); in ip6_finish_output()
132 return ip6_finish_output2(sk, skb); in ip6_finish_output()
135 int ip6_output(struct sock *sk, struct sk_buff *skb) in ip6_output() argument
137 struct net_device *dev = skb_dst(skb)->dev; in ip6_output()
138 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); in ip6_output()
142 kfree_skb(skb); in ip6_output()
146 return NF_HOOK_COND(NFPROTO_IPV6, NF_INET_POST_ROUTING, sk, skb, in ip6_output()
149 !(IP6CB(skb)->flags & IP6SKB_REROUTED)); in ip6_output()
156 int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi6 *fl6, in ip6_xmit() argument
162 struct dst_entry *dst = skb_dst(skb); in ip6_xmit()
165 int seg_len = skb->len; in ip6_xmit()
179 if (skb_headroom(skb) < head_room) { in ip6_xmit()
180 struct sk_buff *skb2 = skb_realloc_headroom(skb, head_room); in ip6_xmit()
182 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), in ip6_xmit()
184 kfree_skb(skb); in ip6_xmit()
187 consume_skb(skb); in ip6_xmit()
188 skb = skb2; in ip6_xmit()
189 skb_set_owner_w(skb, sk); in ip6_xmit()
192 ipv6_push_frag_opts(skb, opt, &proto); in ip6_xmit()
194 ipv6_push_nfrag_opts(skb, opt, &proto, &first_hop); in ip6_xmit()
197 skb_push(skb, sizeof(struct ipv6hdr)); in ip6_xmit()
198 skb_reset_network_header(skb); in ip6_xmit()
199 hdr = ipv6_hdr(skb); in ip6_xmit()
209 ip6_flow_hdr(hdr, tclass, ip6_make_flowlabel(net, skb, fl6->flowlabel, in ip6_xmit()
219 skb->protocol = htons(ETH_P_IPV6); in ip6_xmit()
220 skb->priority = sk->sk_priority; in ip6_xmit()
221 skb->mark = sk->sk_mark; in ip6_xmit()
224 if ((skb->len <= mtu) || skb->ignore_df || skb_is_gso(skb)) { in ip6_xmit()
225 IP6_UPD_PO_STATS(net, ip6_dst_idev(skb_dst(skb)), in ip6_xmit()
226 IPSTATS_MIB_OUT, skb->len); in ip6_xmit()
227 return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_OUT, sk, skb, in ip6_xmit()
231 skb->dev = dst->dev; in ip6_xmit()
233 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_FRAGFAILS); in ip6_xmit()
234 kfree_skb(skb); in ip6_xmit()
239 static int ip6_call_ra_chain(struct sk_buff *skb, int sel) in ip6_call_ra_chain() argument
249 sk->sk_bound_dev_if == skb->dev->ifindex)) { in ip6_call_ra_chain()
251 struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); in ip6_call_ra_chain()
260 rawv6_rcv(last, skb); in ip6_call_ra_chain()
268 static int ip6_forward_proxy_check(struct sk_buff *skb) in ip6_forward_proxy_check() argument
270 struct ipv6hdr *hdr = ipv6_hdr(skb); in ip6_forward_proxy_check()
276 offset = ipv6_skip_exthdr(skb, sizeof(*hdr), &nexthdr, &frag_off); in ip6_forward_proxy_check()
285 if (!pskb_may_pull(skb, (skb_network_header(skb) + in ip6_forward_proxy_check()
286 offset + 1 - skb->data))) in ip6_forward_proxy_check()
289 icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset); in ip6_forward_proxy_check()
313 dst_link_failure(skb); in ip6_forward_proxy_check()
320 static inline int ip6_forward_finish(struct sock *sk, struct sk_buff *skb) in ip6_forward_finish() argument
322 skb_sender_cpu_clear(skb); in ip6_forward_finish()
323 return dst_output_sk(sk, skb); in ip6_forward_finish()
347 static bool ip6_pkt_too_big(const struct sk_buff *skb, unsigned int mtu) in ip6_pkt_too_big() argument
349 if (skb->len <= mtu) in ip6_pkt_too_big()
353 if (IP6CB(skb)->frag_max_size && IP6CB(skb)->frag_max_size > mtu) in ip6_pkt_too_big()
356 if (skb->ignore_df) in ip6_pkt_too_big()
359 if (skb_is_gso(skb) && skb_gso_network_seglen(skb) <= mtu) in ip6_pkt_too_big()
365 int ip6_forward(struct sk_buff *skb) in ip6_forward() argument
367 struct dst_entry *dst = skb_dst(skb); in ip6_forward()
368 struct ipv6hdr *hdr = ipv6_hdr(skb); in ip6_forward()
369 struct inet6_skb_parm *opt = IP6CB(skb); in ip6_forward()
376 if (skb->pkt_type != PACKET_HOST) in ip6_forward()
379 if (unlikely(skb->sk)) in ip6_forward()
382 if (skb_warn_if_lro(skb)) in ip6_forward()
385 if (!xfrm6_policy_check(NULL, XFRM_POLICY_FWD, skb)) { in ip6_forward()
391 skb_forward_csum(skb); in ip6_forward()
407 if (ip6_call_ra_chain(skb, ntohs(opt->ra))) in ip6_forward()
416 skb->dev = dst->dev; in ip6_forward()
417 icmpv6_send(skb, ICMPV6_TIME_EXCEED, ICMPV6_EXC_HOPLIMIT, 0); in ip6_forward()
421 kfree_skb(skb); in ip6_forward()
427 pneigh_lookup(&nd_tbl, net, &hdr->daddr, skb->dev, 0)) { in ip6_forward()
428 int proxied = ip6_forward_proxy_check(skb); in ip6_forward()
430 return ip6_input(skb); in ip6_forward()
438 if (!xfrm6_route_forward(skb)) { in ip6_forward()
443 dst = skb_dst(skb); in ip6_forward()
449 if (skb->dev == dst->dev && opt->srcrt == 0 && !skb_sec_path(skb)) { in ip6_forward()
471 ndisc_send_redirect(skb, target); in ip6_forward()
482 icmpv6_send(skb, ICMPV6_DEST_UNREACH, in ip6_forward()
492 if (ip6_pkt_too_big(skb, mtu)) { in ip6_forward()
494 skb->dev = dst->dev; in ip6_forward()
495 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); in ip6_forward()
500 kfree_skb(skb); in ip6_forward()
504 if (skb_cow(skb, dst->dev->hard_header_len)) { in ip6_forward()
510 hdr = ipv6_hdr(skb); in ip6_forward()
517 IP6_ADD_STATS_BH(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTOCTETS, skb->len); in ip6_forward()
518 return NF_HOOK(NFPROTO_IPV6, NF_INET_FORWARD, NULL, skb, in ip6_forward()
519 skb->dev, dst->dev, in ip6_forward()
525 kfree_skb(skb); in ip6_forward()
546 int ip6_fragment(struct sock *sk, struct sk_buff *skb, in ip6_fragment() argument
550 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); in ip6_fragment()
551 struct ipv6_pinfo *np = skb->sk && !dev_recursion_level() ? in ip6_fragment()
552 inet6_sk(skb->sk) : NULL; in ip6_fragment()
560 struct net *net = dev_net(skb_dst(skb)->dev); in ip6_fragment()
562 hlen = ip6_find_1stfragopt(skb, &prevhdr); in ip6_fragment()
565 mtu = ip6_skb_dst_mtu(skb); in ip6_fragment()
570 if (unlikely(!skb->ignore_df && skb->len > mtu) || in ip6_fragment()
571 (IP6CB(skb)->frag_max_size && in ip6_fragment()
572 IP6CB(skb)->frag_max_size > mtu)) { in ip6_fragment()
573 if (skb->sk && dst_allfrag(skb_dst(skb))) in ip6_fragment()
574 sk_nocaps_add(skb->sk, NETIF_F_GSO_MASK); in ip6_fragment()
576 skb->dev = skb_dst(skb)->dev; in ip6_fragment()
577 icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu); in ip6_fragment()
578 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), in ip6_fragment()
580 kfree_skb(skb); in ip6_fragment()
590 if (skb_has_frag_list(skb)) { in ip6_fragment()
591 int first_len = skb_pagelen(skb); in ip6_fragment()
596 skb_cloned(skb)) in ip6_fragment()
599 skb_walk_frags(skb, frag) { in ip6_fragment()
611 if (skb->sk) { in ip6_fragment()
612 frag->sk = skb->sk; in ip6_fragment()
615 skb->truesize -= frag->truesize; in ip6_fragment()
620 frag = skb_shinfo(skb)->frag_list; in ip6_fragment()
621 skb_frag_list_init(skb); in ip6_fragment()
625 tmp_hdr = kmemdup(skb_network_header(skb), hlen, GFP_ATOMIC); in ip6_fragment()
627 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), in ip6_fragment()
632 __skb_pull(skb, hlen); in ip6_fragment()
633 fh = (struct frag_hdr *)__skb_push(skb, sizeof(struct frag_hdr)); in ip6_fragment()
634 __skb_push(skb, hlen); in ip6_fragment()
635 skb_reset_network_header(skb); in ip6_fragment()
636 memcpy(skb_network_header(skb), tmp_hdr, hlen); in ip6_fragment()
644 first_len = skb_pagelen(skb); in ip6_fragment()
645 skb->data_len = first_len - skb_headlen(skb); in ip6_fragment()
646 skb->len = first_len; in ip6_fragment()
647 ipv6_hdr(skb)->payload_len = htons(first_len - in ip6_fragment()
663 offset += skb->len - hlen - sizeof(struct frag_hdr); in ip6_fragment()
673 ip6_copy_metadata(frag, skb); in ip6_fragment()
676 err = output(sk, skb); in ip6_fragment()
684 skb = frag; in ip6_fragment()
685 frag = skb->next; in ip6_fragment()
686 skb->next = NULL; in ip6_fragment()
706 skb_walk_frags(skb, frag2) { in ip6_fragment()
711 skb->truesize += frag2->truesize; in ip6_fragment()
716 if ((skb->ip_summed == CHECKSUM_PARTIAL) && in ip6_fragment()
717 skb_checksum_help(skb)) in ip6_fragment()
720 left = skb->len - hlen; /* Space per frame */ in ip6_fragment()
749 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), in ip6_fragment()
759 ip6_copy_metadata(frag, skb); in ip6_fragment()
771 if (skb->sk) in ip6_fragment()
772 skb_set_owner_w(frag, skb->sk); in ip6_fragment()
777 skb_copy_from_linear_data(skb, skb_network_header(frag), hlen); in ip6_fragment()
793 BUG_ON(skb_copy_bits(skb, ptr, skb_transport_header(frag), in ip6_fragment()
813 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), in ip6_fragment()
816 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), in ip6_fragment()
818 consume_skb(skb); in ip6_fragment()
822 IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), in ip6_fragment()
824 kfree_skb(skb); in ip6_fragment()
1067 int odd, struct sk_buff *skb), in ip6_ufo_append_data() argument
1073 struct sk_buff *skb; in ip6_ufo_append_data() local
1081 skb = skb_peek_tail(queue); in ip6_ufo_append_data()
1082 if (!skb) { in ip6_ufo_append_data()
1083 skb = sock_alloc_send_skb(sk, in ip6_ufo_append_data()
1086 if (!skb) in ip6_ufo_append_data()
1090 skb_reserve(skb, hh_len); in ip6_ufo_append_data()
1093 skb_put(skb, fragheaderlen + transhdrlen); in ip6_ufo_append_data()
1096 skb_reset_network_header(skb); in ip6_ufo_append_data()
1099 skb->transport_header = skb->network_header + fragheaderlen; in ip6_ufo_append_data()
1101 skb->protocol = htons(ETH_P_IPV6); in ip6_ufo_append_data()
1102 skb->csum = 0; in ip6_ufo_append_data()
1104 __skb_queue_tail(queue, skb); in ip6_ufo_append_data()
1105 } else if (skb_is_gso(skb)) { in ip6_ufo_append_data()
1109 skb->ip_summed = CHECKSUM_PARTIAL; in ip6_ufo_append_data()
1113 skb_shinfo(skb)->gso_size = (mtu - fragheaderlen - in ip6_ufo_append_data()
1115 skb_shinfo(skb)->gso_type = SKB_GSO_UDP; in ip6_ufo_append_data()
1117 skb_shinfo(skb)->ip6_frag_id = fhdr.identification; in ip6_ufo_append_data()
1120 return skb_append_datato_frags(sk, skb, getfrag, from, in ip6_ufo_append_data()
1139 struct sk_buff *skb, in ip6_append_data_mtu() argument
1144 if (!skb) { in ip6_append_data_mtu()
1235 int len, int odd, struct sk_buff *skb), in __ip6_append_data() argument
1239 struct sk_buff *skb, *skb_prev = NULL; in __ip6_append_data() local
1253 skb = skb_peek_tail(queue); in __ip6_append_data()
1254 if (!skb) { in __ip6_append_data()
1336 (skb && skb_is_gso(skb))) && in __ip6_append_data()
1348 if (!skb) in __ip6_append_data()
1353 copy = (cork->length <= mtu && !(cork->flags & IPCORK_ALLFRAG) ? mtu : maxfraglen) - skb->len; in __ip6_append_data()
1355 copy = maxfraglen - skb->len; in __ip6_append_data()
1365 if (skb) in __ip6_append_data()
1366 fraggap = skb->len - maxfraglen; in __ip6_append_data()
1370 if (!skb || !skb_prev) in __ip6_append_data()
1372 fragheaderlen, skb, rt, in __ip6_append_data()
1375 skb_prev = skb; in __ip6_append_data()
1412 skb = sock_alloc_send_skb(sk, in __ip6_append_data()
1416 skb = NULL; in __ip6_append_data()
1419 skb = sock_wmalloc(sk, in __ip6_append_data()
1422 if (unlikely(!skb)) in __ip6_append_data()
1425 if (!skb) in __ip6_append_data()
1430 skb->protocol = htons(ETH_P_IPV6); in __ip6_append_data()
1431 skb->ip_summed = csummode; in __ip6_append_data()
1432 skb->csum = 0; in __ip6_append_data()
1434 skb_reserve(skb, hh_len + sizeof(struct frag_hdr) + in __ip6_append_data()
1438 skb_shinfo(skb)->tx_flags = tx_flags; in __ip6_append_data()
1440 skb_shinfo(skb)->tskey = tskey; in __ip6_append_data()
1446 data = skb_put(skb, fraglen); in __ip6_append_data()
1447 skb_set_network_header(skb, exthdrlen); in __ip6_append_data()
1449 skb->transport_header = (skb->network_header + in __ip6_append_data()
1452 skb->csum = skb_copy_and_csum_bits( in __ip6_append_data()
1456 skb->csum); in __ip6_append_data()
1464 kfree_skb(skb); in __ip6_append_data()
1466 } else if (copy > 0 && getfrag(from, data + transhdrlen, offset, copy, fraggap, skb) < 0) { in __ip6_append_data()
1468 kfree_skb(skb); in __ip6_append_data()
1481 __skb_queue_tail(queue, skb); in __ip6_append_data()
1491 off = skb->len; in __ip6_append_data()
1492 if (getfrag(from, skb_put(skb, copy), in __ip6_append_data()
1493 offset, copy, off, skb) < 0) { in __ip6_append_data()
1494 __skb_trim(skb, off); in __ip6_append_data()
1499 int i = skb_shinfo(skb)->nr_frags; in __ip6_append_data()
1505 if (!skb_can_coalesce(skb, i, pfrag->page, in __ip6_append_data()
1511 __skb_fill_page_desc(skb, i, pfrag->page, in __ip6_append_data()
1513 skb_shinfo(skb)->nr_frags = ++i; in __ip6_append_data()
1519 offset, copy, skb->len, skb) < 0) in __ip6_append_data()
1523 skb_frag_size_add(&skb_shinfo(skb)->frags[i - 1], copy); in __ip6_append_data()
1524 skb->len += copy; in __ip6_append_data()
1525 skb->data_len += copy; in __ip6_append_data()
1526 skb->truesize += copy; in __ip6_append_data()
1545 int odd, struct sk_buff *skb), in ip6_append_data() argument
1605 struct sk_buff *skb, *tmp_skb; in __ip6_make_skb() local
1616 skb = __skb_dequeue(queue); in __ip6_make_skb()
1617 if (!skb) in __ip6_make_skb()
1619 tail_skb = &(skb_shinfo(skb)->frag_list); in __ip6_make_skb()
1622 if (skb->data < skb_network_header(skb)) in __ip6_make_skb()
1623 __skb_pull(skb, skb_network_offset(skb)); in __ip6_make_skb()
1625 __skb_pull(tmp_skb, skb_network_header_len(skb)); in __ip6_make_skb()
1628 skb->len += tmp_skb->len; in __ip6_make_skb()
1629 skb->data_len += tmp_skb->len; in __ip6_make_skb()
1630 skb->truesize += tmp_skb->truesize; in __ip6_make_skb()
1636 skb->ignore_df = ip6_sk_ignore_df(sk); in __ip6_make_skb()
1639 __skb_pull(skb, skb_network_header_len(skb)); in __ip6_make_skb()
1641 ipv6_push_frag_opts(skb, opt, &proto); in __ip6_make_skb()
1643 ipv6_push_nfrag_opts(skb, opt, &proto, &final_dst); in __ip6_make_skb()
1645 skb_push(skb, sizeof(struct ipv6hdr)); in __ip6_make_skb()
1646 skb_reset_network_header(skb); in __ip6_make_skb()
1647 hdr = ipv6_hdr(skb); in __ip6_make_skb()
1650 ip6_make_flowlabel(net, skb, fl6->flowlabel, in __ip6_make_skb()
1657 skb->priority = sk->sk_priority; in __ip6_make_skb()
1658 skb->mark = sk->sk_mark; in __ip6_make_skb()
1660 skb_dst_set(skb, dst_clone(&rt->dst)); in __ip6_make_skb()
1661 IP6_UPD_PO_STATS(net, rt->rt6i_idev, IPSTATS_MIB_OUT, skb->len); in __ip6_make_skb()
1663 struct inet6_dev *idev = ip6_dst_idev(skb_dst(skb)); in __ip6_make_skb()
1665 ICMP6MSGOUT_INC_STATS(net, idev, icmp6_hdr(skb)->icmp6_type); in __ip6_make_skb()
1671 return skb; in __ip6_make_skb()
1674 int ip6_send_skb(struct sk_buff *skb) in ip6_send_skb() argument
1676 struct net *net = sock_net(skb->sk); in ip6_send_skb()
1677 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb); in ip6_send_skb()
1680 err = ip6_local_out(skb); in ip6_send_skb()
1694 struct sk_buff *skb; in ip6_push_pending_frames() local
1696 skb = ip6_finish_skb(sk); in ip6_push_pending_frames()
1697 if (!skb) in ip6_push_pending_frames()
1700 return ip6_send_skb(skb); in ip6_push_pending_frames()
1709 struct sk_buff *skb; in __ip6_flush_pending_frames() local
1711 while ((skb = __skb_dequeue_tail(queue)) != NULL) { in __ip6_flush_pending_frames()
1712 if (skb_dst(skb)) in __ip6_flush_pending_frames()
1713 IP6_INC_STATS(sock_net(sk), ip6_dst_idev(skb_dst(skb)), in __ip6_flush_pending_frames()
1715 kfree_skb(skb); in __ip6_flush_pending_frames()
1730 int len, int odd, struct sk_buff *skb), in ip6_make_skb() argument