diff options
Diffstat (limited to 'include/linux/skbuff.h')
-rw-r--r-- | include/linux/skbuff.h | 74 |
1 files changed, 58 insertions, 16 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 85ab7d72b54c..30007afe70b3 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -83,11 +83,15 @@ | |||
83 | * | 83 | * |
84 | * CHECKSUM_PARTIAL: | 84 | * CHECKSUM_PARTIAL: |
85 | * | 85 | * |
86 | * This is identical to the case for output below. This may occur on a packet | 86 | * A checksum is set up to be offloaded to a device as described in the |
87 | * output description for CHECKSUM_PARTIAL. This may occur on a packet | ||
87 | * received directly from another Linux OS, e.g., a virtualized Linux kernel | 88 | * received directly from another Linux OS, e.g., a virtualized Linux kernel |
88 | * on the same host. The packet can be treated in the same way as | 89 | * on the same host, or it may be set in the input path in GRO or remote |
89 | * CHECKSUM_UNNECESSARY, except that on output (i.e., forwarding) the | 90 | * checksum offload. For the purposes of checksum verification, the checksum |
90 | * checksum must be filled in by the OS or the hardware. | 91 | * referred to by skb->csum_start + skb->csum_offset and any preceding |
92 | * checksums in the packet are considered verified. Any checksums in the | ||
93 | * packet that are after the checksum being offloaded are not considered to | ||
94 | * be verified. | ||
91 | * | 95 | * |
92 | * B. Checksumming on output. | 96 | * B. Checksumming on output. |
93 | * | 97 | * |
@@ -626,8 +630,11 @@ struct sk_buff { | |||
626 | __u32 hash; | 630 | __u32 hash; |
627 | __be16 vlan_proto; | 631 | __be16 vlan_proto; |
628 | __u16 vlan_tci; | 632 | __u16 vlan_tci; |
629 | #ifdef CONFIG_NET_RX_BUSY_POLL | 633 | #if defined(CONFIG_NET_RX_BUSY_POLL) || defined(CONFIG_XPS) |
630 | unsigned int napi_id; | 634 | union { |
635 | unsigned int napi_id; | ||
636 | unsigned int sender_cpu; | ||
637 | }; | ||
631 | #endif | 638 | #endif |
632 | #ifdef CONFIG_NETWORK_SECMARK | 639 | #ifdef CONFIG_NETWORK_SECMARK |
633 | __u32 secmark; | 640 | __u32 secmark; |
@@ -2484,19 +2491,18 @@ static inline int skb_put_padto(struct sk_buff *skb, unsigned int len) | |||
2484 | } | 2491 | } |
2485 | 2492 | ||
2486 | static inline int skb_add_data(struct sk_buff *skb, | 2493 | static inline int skb_add_data(struct sk_buff *skb, |
2487 | char __user *from, int copy) | 2494 | struct iov_iter *from, int copy) |
2488 | { | 2495 | { |
2489 | const int off = skb->len; | 2496 | const int off = skb->len; |
2490 | 2497 | ||
2491 | if (skb->ip_summed == CHECKSUM_NONE) { | 2498 | if (skb->ip_summed == CHECKSUM_NONE) { |
2492 | int err = 0; | 2499 | __wsum csum = 0; |
2493 | __wsum csum = csum_and_copy_from_user(from, skb_put(skb, copy), | 2500 | if (csum_and_copy_from_iter(skb_put(skb, copy), copy, |
2494 | copy, 0, &err); | 2501 | &csum, from) == copy) { |
2495 | if (!err) { | ||
2496 | skb->csum = csum_block_add(skb->csum, csum, off); | 2502 | skb->csum = csum_block_add(skb->csum, csum, off); |
2497 | return 0; | 2503 | return 0; |
2498 | } | 2504 | } |
2499 | } else if (!copy_from_user(skb_put(skb, copy), from, copy)) | 2505 | } else if (copy_from_iter(skb_put(skb, copy), copy, from) == copy) |
2500 | return 0; | 2506 | return 0; |
2501 | 2507 | ||
2502 | __skb_trim(skb, off); | 2508 | __skb_trim(skb, off); |
@@ -2693,8 +2699,7 @@ int skb_vlan_push(struct sk_buff *skb, __be16 vlan_proto, u16 vlan_tci); | |||
2693 | 2699 | ||
2694 | static inline int memcpy_from_msg(void *data, struct msghdr *msg, int len) | 2700 | static inline int memcpy_from_msg(void *data, struct msghdr *msg, int len) |
2695 | { | 2701 | { |
2696 | /* XXX: stripping const */ | 2702 | return copy_from_iter(data, len, &msg->msg_iter) == len ? 0 : -EFAULT; |
2697 | return memcpy_fromiovec(data, (struct iovec *)msg->msg_iter.iov, len); | ||
2698 | } | 2703 | } |
2699 | 2704 | ||
2700 | static inline int memcpy_to_msg(struct msghdr *msg, void *data, int len) | 2705 | static inline int memcpy_to_msg(struct msghdr *msg, void *data, int len) |
@@ -2914,7 +2919,10 @@ __sum16 __skb_checksum_complete(struct sk_buff *skb); | |||
2914 | 2919 | ||
2915 | static inline int skb_csum_unnecessary(const struct sk_buff *skb) | 2920 | static inline int skb_csum_unnecessary(const struct sk_buff *skb) |
2916 | { | 2921 | { |
2917 | return ((skb->ip_summed & CHECKSUM_UNNECESSARY) || skb->csum_valid); | 2922 | return ((skb->ip_summed == CHECKSUM_UNNECESSARY) || |
2923 | skb->csum_valid || | ||
2924 | (skb->ip_summed == CHECKSUM_PARTIAL && | ||
2925 | skb_checksum_start_offset(skb) >= 0)); | ||
2918 | } | 2926 | } |
2919 | 2927 | ||
2920 | /** | 2928 | /** |
@@ -3071,7 +3079,7 @@ static inline __wsum null_compute_pseudo(struct sk_buff *skb, int proto) | |||
3071 | 3079 | ||
3072 | #define skb_checksum_validate_zero_check(skb, proto, check, \ | 3080 | #define skb_checksum_validate_zero_check(skb, proto, check, \ |
3073 | compute_pseudo) \ | 3081 | compute_pseudo) \ |
3074 | __skb_checksum_validate_(skb, proto, true, true, check, compute_pseudo) | 3082 | __skb_checksum_validate(skb, proto, true, true, check, compute_pseudo) |
3075 | 3083 | ||
3076 | #define skb_checksum_simple_validate(skb) \ | 3084 | #define skb_checksum_simple_validate(skb) \ |
3077 | __skb_checksum_validate(skb, 0, true, false, 0, null_compute_pseudo) | 3085 | __skb_checksum_validate(skb, 0, true, false, 0, null_compute_pseudo) |
@@ -3096,6 +3104,40 @@ do { \ | |||
3096 | compute_pseudo(skb, proto)); \ | 3104 | compute_pseudo(skb, proto)); \ |
3097 | } while (0) | 3105 | } while (0) |
3098 | 3106 | ||
3107 | static inline void skb_remcsum_adjust_partial(struct sk_buff *skb, void *ptr, | ||
3108 | u16 start, u16 offset) | ||
3109 | { | ||
3110 | skb->ip_summed = CHECKSUM_PARTIAL; | ||
3111 | skb->csum_start = ((unsigned char *)ptr + start) - skb->head; | ||
3112 | skb->csum_offset = offset - start; | ||
3113 | } | ||
3114 | |||
3115 | /* Update skbuf and packet to reflect the remote checksum offload operation. | ||
3116 | * When called, ptr indicates the starting point for skb->csum when | ||
3117 | * ip_summed is CHECKSUM_COMPLETE. If we need create checksum complete | ||
3118 | * here, skb_postpull_rcsum is done so skb->csum start is ptr. | ||
3119 | */ | ||
3120 | static inline void skb_remcsum_process(struct sk_buff *skb, void *ptr, | ||
3121 | int start, int offset, bool nopartial) | ||
3122 | { | ||
3123 | __wsum delta; | ||
3124 | |||
3125 | if (!nopartial) { | ||
3126 | skb_remcsum_adjust_partial(skb, ptr, start, offset); | ||
3127 | return; | ||
3128 | } | ||
3129 | |||
3130 | if (unlikely(skb->ip_summed != CHECKSUM_COMPLETE)) { | ||
3131 | __skb_checksum_complete(skb); | ||
3132 | skb_postpull_rcsum(skb, skb->data, ptr - (void *)skb->data); | ||
3133 | } | ||
3134 | |||
3135 | delta = remcsum_adjust(ptr, skb->csum, start, offset); | ||
3136 | |||
3137 | /* Adjust skb->csum since we changed the packet */ | ||
3138 | skb->csum = csum_add(skb->csum, delta); | ||
3139 | } | ||
3140 | |||
3099 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 3141 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
3100 | void nf_conntrack_destroy(struct nf_conntrack *nfct); | 3142 | void nf_conntrack_destroy(struct nf_conntrack *nfct); |
3101 | static inline void nf_conntrack_put(struct nf_conntrack *nfct) | 3143 | static inline void nf_conntrack_put(struct nf_conntrack *nfct) |