aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/skbuff.c
diff options
context:
space:
mode:
authorJames Morris <james.l.morris@oracle.com>2014-11-19 05:32:12 -0500
committerJames Morris <james.l.morris@oracle.com>2014-11-19 05:32:12 -0500
commitb10778a00d40b3d9fdaaf5891e802794781ff71c (patch)
tree6ba4cbac86eecedc3f30650e7f764ecf00c83898 /net/core/skbuff.c
parent594081ee7145cc30a3977cb4e218f81213b63dc5 (diff)
parentbfe01a5ba2490f299e1d2d5508cbbbadd897bbe9 (diff)
Merge commit 'v3.17' into next
Diffstat (limited to 'net/core/skbuff.c')
-rw-r--r--net/core/skbuff.c82
1 files changed, 76 insertions, 6 deletions
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index c1a33033cbe2..8d289697cc7a 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -62,6 +62,7 @@
62#include <linux/scatterlist.h> 62#include <linux/scatterlist.h>
63#include <linux/errqueue.h> 63#include <linux/errqueue.h>
64#include <linux/prefetch.h> 64#include <linux/prefetch.h>
65#include <linux/if_vlan.h>
65 66
66#include <net/protocol.h> 67#include <net/protocol.h>
67#include <net/dst.h> 68#include <net/dst.h>
@@ -2646,7 +2647,7 @@ EXPORT_SYMBOL(skb_prepare_seq_read);
2646 * skb_seq_read() will return the remaining part of the block. 2647 * skb_seq_read() will return the remaining part of the block.
2647 * 2648 *
2648 * Note 1: The size of each block of data returned can be arbitrary, 2649 * Note 1: The size of each block of data returned can be arbitrary,
2649 * this limitation is the cost for zerocopy seqeuental 2650 * this limitation is the cost for zerocopy sequential
2650 * reads of potentially non linear data. 2651 * reads of potentially non linear data.
2651 * 2652 *
2652 * Note 2: Fragment lists within fragments are not implemented 2653 * Note 2: Fragment lists within fragments are not implemented
@@ -2780,7 +2781,7 @@ EXPORT_SYMBOL(skb_find_text);
2780/** 2781/**
2781 * skb_append_datato_frags - append the user data to a skb 2782 * skb_append_datato_frags - append the user data to a skb
2782 * @sk: sock structure 2783 * @sk: sock structure
2783 * @skb: skb structure to be appened with user data. 2784 * @skb: skb structure to be appended with user data.
2784 * @getfrag: call back function to be used for getting the user data 2785 * @getfrag: call back function to be used for getting the user data
2785 * @from: pointer to user message iov 2786 * @from: pointer to user message iov
2786 * @length: length of the iov message 2787 * @length: length of the iov message
@@ -2976,9 +2977,9 @@ struct sk_buff *skb_segment(struct sk_buff *head_skb,
2976 tail = nskb; 2977 tail = nskb;
2977 2978
2978 __copy_skb_header(nskb, head_skb); 2979 __copy_skb_header(nskb, head_skb);
2979 nskb->mac_len = head_skb->mac_len;
2980 2980
2981 skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom); 2981 skb_headers_offset_update(nskb, skb_headroom(nskb) - headroom);
2982 skb_reset_mac_len(nskb);
2982 2983
2983 skb_copy_from_linear_data_offset(head_skb, -tnl_hlen, 2984 skb_copy_from_linear_data_offset(head_skb, -tnl_hlen,
2984 nskb->data - tnl_hlen, 2985 nskb->data - tnl_hlen,
@@ -3151,6 +3152,9 @@ int skb_gro_receive(struct sk_buff **head, struct sk_buff *skb)
3151 NAPI_GRO_CB(skb)->free = NAPI_GRO_FREE_STOLEN_HEAD; 3152 NAPI_GRO_CB(skb)->free = NAPI_GRO_FREE_STOLEN_HEAD;
3152 goto done; 3153 goto done;
3153 } 3154 }
3155 /* switch back to head shinfo */
3156 pinfo = skb_shinfo(p);
3157
3154 if (pinfo->frag_list) 3158 if (pinfo->frag_list)
3155 goto merge; 3159 goto merge;
3156 if (skb_gro_len(p) != pinfo->gso_size) 3160 if (skb_gro_len(p) != pinfo->gso_size)
@@ -3490,10 +3494,10 @@ int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb)
3490} 3494}
3491EXPORT_SYMBOL(sock_queue_err_skb); 3495EXPORT_SYMBOL(sock_queue_err_skb);
3492 3496
3493void skb_tstamp_tx(struct sk_buff *orig_skb, 3497void __skb_tstamp_tx(struct sk_buff *orig_skb,
3494 struct skb_shared_hwtstamps *hwtstamps) 3498 struct skb_shared_hwtstamps *hwtstamps,
3499 struct sock *sk, int tstype)
3495{ 3500{
3496 struct sock *sk = orig_skb->sk;
3497 struct sock_exterr_skb *serr; 3501 struct sock_exterr_skb *serr;
3498 struct sk_buff *skb; 3502 struct sk_buff *skb;
3499 int err; 3503 int err;
@@ -3521,12 +3525,26 @@ void skb_tstamp_tx(struct sk_buff *orig_skb,
3521 memset(serr, 0, sizeof(*serr)); 3525 memset(serr, 0, sizeof(*serr));
3522 serr->ee.ee_errno = ENOMSG; 3526 serr->ee.ee_errno = ENOMSG;
3523 serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING; 3527 serr->ee.ee_origin = SO_EE_ORIGIN_TIMESTAMPING;
3528 serr->ee.ee_info = tstype;
3529 if (sk->sk_tsflags & SOF_TIMESTAMPING_OPT_ID) {
3530 serr->ee.ee_data = skb_shinfo(skb)->tskey;
3531 if (sk->sk_protocol == IPPROTO_TCP)
3532 serr->ee.ee_data -= sk->sk_tskey;
3533 }
3524 3534
3525 err = sock_queue_err_skb(sk, skb); 3535 err = sock_queue_err_skb(sk, skb);
3526 3536
3527 if (err) 3537 if (err)
3528 kfree_skb(skb); 3538 kfree_skb(skb);
3529} 3539}
3540EXPORT_SYMBOL_GPL(__skb_tstamp_tx);
3541
3542void skb_tstamp_tx(struct sk_buff *orig_skb,
3543 struct skb_shared_hwtstamps *hwtstamps)
3544{
3545 return __skb_tstamp_tx(orig_skb, hwtstamps, orig_skb->sk,
3546 SCM_TSTAMP_SND);
3547}
3530EXPORT_SYMBOL_GPL(skb_tstamp_tx); 3548EXPORT_SYMBOL_GPL(skb_tstamp_tx);
3531 3549
3532void skb_complete_wifi_ack(struct sk_buff *skb, bool acked) 3550void skb_complete_wifi_ack(struct sk_buff *skb, bool acked)
@@ -3959,3 +3977,55 @@ unsigned int skb_gso_transport_seglen(const struct sk_buff *skb)
3959 return shinfo->gso_size; 3977 return shinfo->gso_size;
3960} 3978}
3961EXPORT_SYMBOL_GPL(skb_gso_transport_seglen); 3979EXPORT_SYMBOL_GPL(skb_gso_transport_seglen);
3980
3981static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb)
3982{
3983 if (skb_cow(skb, skb_headroom(skb)) < 0) {
3984 kfree_skb(skb);
3985 return NULL;
3986 }
3987
3988 memmove(skb->data - ETH_HLEN, skb->data - VLAN_ETH_HLEN, 2 * ETH_ALEN);
3989 skb->mac_header += VLAN_HLEN;
3990 return skb;
3991}
3992
3993struct sk_buff *skb_vlan_untag(struct sk_buff *skb)
3994{
3995 struct vlan_hdr *vhdr;
3996 u16 vlan_tci;
3997
3998 if (unlikely(vlan_tx_tag_present(skb))) {
3999 /* vlan_tci is already set-up so leave this for another time */
4000 return skb;
4001 }
4002
4003 skb = skb_share_check(skb, GFP_ATOMIC);
4004 if (unlikely(!skb))
4005 goto err_free;
4006
4007 if (unlikely(!pskb_may_pull(skb, VLAN_HLEN)))
4008 goto err_free;
4009
4010 vhdr = (struct vlan_hdr *)skb->data;
4011 vlan_tci = ntohs(vhdr->h_vlan_TCI);
4012 __vlan_hwaccel_put_tag(skb, skb->protocol, vlan_tci);
4013
4014 skb_pull_rcsum(skb, VLAN_HLEN);
4015 vlan_set_encap_proto(skb, vhdr);
4016
4017 skb = skb_reorder_vlan_header(skb);
4018 if (unlikely(!skb))
4019 goto err_free;
4020
4021 skb_reset_network_header(skb);
4022 skb_reset_transport_header(skb);
4023 skb_reset_mac_len(skb);
4024
4025 return skb;
4026
4027err_free:
4028 kfree_skb(skb);
4029 return NULL;
4030}
4031EXPORT_SYMBOL(skb_vlan_untag);