diff options
Diffstat (limited to 'net/ipv4/ipvs')
-rw-r--r-- | net/ipv4/ipvs/ip_vs_core.c | 26 |
1 files changed, 10 insertions, 16 deletions
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c index fbca2a2ff29f..3487337192c6 100644 --- a/net/ipv4/ipvs/ip_vs_core.c +++ b/net/ipv4/ipvs/ip_vs_core.c | |||
@@ -541,13 +541,14 @@ __sum16 ip_vs_checksum_complete(struct sk_buff *skb, int offset) | |||
541 | return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); | 541 | return csum_fold(skb_checksum(skb, offset, skb->len - offset, 0)); |
542 | } | 542 | } |
543 | 543 | ||
544 | static inline struct sk_buff * | 544 | static inline int ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user) |
545 | ip_vs_gather_frags(struct sk_buff *skb, u_int32_t user) | ||
546 | { | 545 | { |
547 | skb = ip_defrag(skb, user); | 546 | int err = ip_defrag(skb, user); |
548 | if (skb) | 547 | |
548 | if (!err) | ||
549 | ip_send_check(ip_hdr(skb)); | 549 | ip_send_check(ip_hdr(skb)); |
550 | return skb; | 550 | |
551 | return err; | ||
551 | } | 552 | } |
552 | 553 | ||
553 | /* | 554 | /* |
@@ -619,10 +620,8 @@ static int ip_vs_out_icmp(struct sk_buff **pskb, int *related) | |||
619 | 620 | ||
620 | /* reassemble IP fragments */ | 621 | /* reassemble IP fragments */ |
621 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { | 622 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { |
622 | skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT); | 623 | if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT)) |
623 | if (!skb) | ||
624 | return NF_STOLEN; | 624 | return NF_STOLEN; |
625 | *pskb = skb; | ||
626 | } | 625 | } |
627 | 626 | ||
628 | iph = ip_hdr(skb); | 627 | iph = ip_hdr(skb); |
@@ -756,11 +755,9 @@ ip_vs_out(unsigned int hooknum, struct sk_buff **pskb, | |||
756 | /* reassemble IP fragments */ | 755 | /* reassemble IP fragments */ |
757 | if (unlikely(iph->frag_off & htons(IP_MF|IP_OFFSET) && | 756 | if (unlikely(iph->frag_off & htons(IP_MF|IP_OFFSET) && |
758 | !pp->dont_defrag)) { | 757 | !pp->dont_defrag)) { |
759 | skb = ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT); | 758 | if (ip_vs_gather_frags(skb, IP_DEFRAG_VS_OUT)) |
760 | if (!skb) | ||
761 | return NF_STOLEN; | 759 | return NF_STOLEN; |
762 | iph = ip_hdr(skb); | 760 | iph = ip_hdr(skb); |
763 | *pskb = skb; | ||
764 | } | 761 | } |
765 | 762 | ||
766 | ihl = iph->ihl << 2; | 763 | ihl = iph->ihl << 2; |
@@ -861,12 +858,9 @@ ip_vs_in_icmp(struct sk_buff **pskb, int *related, unsigned int hooknum) | |||
861 | 858 | ||
862 | /* reassemble IP fragments */ | 859 | /* reassemble IP fragments */ |
863 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { | 860 | if (ip_hdr(skb)->frag_off & htons(IP_MF | IP_OFFSET)) { |
864 | skb = ip_vs_gather_frags(skb, | 861 | if (ip_vs_gather_frags(skb, hooknum == NF_IP_LOCAL_IN ? |
865 | hooknum == NF_IP_LOCAL_IN ? | 862 | IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD)) |
866 | IP_DEFRAG_VS_IN : IP_DEFRAG_VS_FWD); | ||
867 | if (!skb) | ||
868 | return NF_STOLEN; | 863 | return NF_STOLEN; |
869 | *pskb = skb; | ||
870 | } | 864 | } |
871 | 865 | ||
872 | iph = ip_hdr(skb); | 866 | iph = ip_hdr(skb); |