diff options
author | Tom Herbert <therbert@google.com> | 2014-05-02 19:29:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-05 15:26:29 -0400 |
commit | 76ba0aae673075c77a8b775e9133c8e8b1a44563 (patch) | |
tree | 503e545954aca2b7a2359bf38719acdaaae6707b /include/linux/skbuff.h | |
parent | 20fce54fa74a55ad1e821b61612393d7159b6af8 (diff) |
net: Generalize checksum_init functions
Create a general __skb_checksum_validate function (actually a
macro) to subsume the various checksum_init functions. This
function can either init the checksum, or do the full validation
(logically checksum_init+skb_check_complete)-- a flag specifies
if full vaidation is performed. Also, there is a flag to the function
to indicate that zero checksums are allowed (to support optional
UDP checksums).
Added several stub functions for calling __skb_checksum_validate.
Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'include/linux/skbuff.h')
-rw-r--r-- | include/linux/skbuff.h | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index 08074a810164..3ca0dda5a42e 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -2741,6 +2741,99 @@ static inline __sum16 skb_checksum_complete(struct sk_buff *skb) | |||
2741 | 0 : __skb_checksum_complete(skb); | 2741 | 0 : __skb_checksum_complete(skb); |
2742 | } | 2742 | } |
2743 | 2743 | ||
2744 | /* Check if we need to perform checksum complete validation. | ||
2745 | * | ||
2746 | * Returns true if checksum complete is needed, false otherwise | ||
2747 | * (either checksum is unnecessary or zero checksum is allowed). | ||
2748 | */ | ||
2749 | static inline bool __skb_checksum_validate_needed(struct sk_buff *skb, | ||
2750 | bool zero_okay, | ||
2751 | __sum16 check) | ||
2752 | { | ||
2753 | if (skb_csum_unnecessary(skb)) { | ||
2754 | return false; | ||
2755 | } else if (zero_okay && !check) { | ||
2756 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
2757 | return false; | ||
2758 | } | ||
2759 | |||
2760 | return true; | ||
2761 | } | ||
2762 | |||
2763 | /* For small packets <= CHECKSUM_BREAK peform checksum complete directly | ||
2764 | * in checksum_init. | ||
2765 | */ | ||
2766 | #define CHECKSUM_BREAK 76 | ||
2767 | |||
2768 | /* Validate (init) checksum based on checksum complete. | ||
2769 | * | ||
2770 | * Return values: | ||
2771 | * 0: checksum is validated or try to in skb_checksum_complete. In the latter | ||
2772 | * case the ip_summed will not be CHECKSUM_UNNECESSARY and the pseudo | ||
2773 | * checksum is stored in skb->csum for use in __skb_checksum_complete | ||
2774 | * non-zero: value of invalid checksum | ||
2775 | * | ||
2776 | */ | ||
2777 | static inline __sum16 __skb_checksum_validate_complete(struct sk_buff *skb, | ||
2778 | bool complete, | ||
2779 | __wsum psum) | ||
2780 | { | ||
2781 | if (skb->ip_summed == CHECKSUM_COMPLETE) { | ||
2782 | if (!csum_fold(csum_add(psum, skb->csum))) { | ||
2783 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
2784 | return 0; | ||
2785 | } | ||
2786 | } | ||
2787 | |||
2788 | skb->csum = psum; | ||
2789 | |||
2790 | if (complete || skb->len <= CHECKSUM_BREAK) | ||
2791 | return __skb_checksum_complete(skb); | ||
2792 | |||
2793 | return 0; | ||
2794 | } | ||
2795 | |||
2796 | static inline __wsum null_compute_pseudo(struct sk_buff *skb, int proto) | ||
2797 | { | ||
2798 | return 0; | ||
2799 | } | ||
2800 | |||
2801 | /* Perform checksum validate (init). Note that this is a macro since we only | ||
2802 | * want to calculate the pseudo header which is an input function if necessary. | ||
2803 | * First we try to validate without any computation (checksum unnecessary) and | ||
2804 | * then calculate based on checksum complete calling the function to compute | ||
2805 | * pseudo header. | ||
2806 | * | ||
2807 | * Return values: | ||
2808 | * 0: checksum is validated or try to in skb_checksum_complete | ||
2809 | * non-zero: value of invalid checksum | ||
2810 | */ | ||
2811 | #define __skb_checksum_validate(skb, proto, complete, \ | ||
2812 | zero_okay, check, compute_pseudo) \ | ||
2813 | ({ \ | ||
2814 | __sum16 __ret = 0; \ | ||
2815 | if (__skb_checksum_validate_needed(skb, zero_okay, check)) \ | ||
2816 | __ret = __skb_checksum_validate_complete(skb, \ | ||
2817 | complete, compute_pseudo(skb, proto)); \ | ||
2818 | __ret; \ | ||
2819 | }) | ||
2820 | |||
2821 | #define skb_checksum_init(skb, proto, compute_pseudo) \ | ||
2822 | __skb_checksum_validate(skb, proto, false, false, 0, compute_pseudo) | ||
2823 | |||
2824 | #define skb_checksum_init_zero_check(skb, proto, check, compute_pseudo) \ | ||
2825 | __skb_checksum_validate(skb, proto, false, true, check, compute_pseudo) | ||
2826 | |||
2827 | #define skb_checksum_validate(skb, proto, compute_pseudo) \ | ||
2828 | __skb_checksum_validate(skb, proto, true, false, 0, compute_pseudo) | ||
2829 | |||
2830 | #define skb_checksum_validate_zero_check(skb, proto, check, \ | ||
2831 | compute_pseudo) \ | ||
2832 | __skb_checksum_validate_(skb, proto, true, true, check, compute_pseudo) | ||
2833 | |||
2834 | #define skb_checksum_simple_validate(skb) \ | ||
2835 | __skb_checksum_validate(skb, 0, true, false, 0, null_compute_pseudo) | ||
2836 | |||
2744 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) | 2837 | #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) |
2745 | void nf_conntrack_destroy(struct nf_conntrack *nfct); | 2838 | void nf_conntrack_destroy(struct nf_conntrack *nfct); |
2746 | static inline void nf_conntrack_put(struct nf_conntrack *nfct) | 2839 | static inline void nf_conntrack_put(struct nf_conntrack *nfct) |