@@ -2741,6 +2741,99 @@ static inline __sum16 skb_checksum_complete(struct sk_buff *skb)
2741
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
2837
#if defined(CONFIG_NF_CONNTRACK ) || defined(CONFIG_NF_CONNTRACK_MODULE )
2745
2838
void nf_conntrack_destroy (struct nf_conntrack * nfct );
2746
2839
static inline void nf_conntrack_put (struct nf_conntrack * nfct )
0 commit comments