@ -121,6 +121,7 @@ udp_snat_handler(struct sk_buff *skb,
struct udphdr * udph ;
unsigned int udphoff ;
int oldlen ;
int payload_csum = 0 ;
# ifdef CONFIG_IP_VS_IPV6
if ( cp - > af = = AF_INET6 )
@ -135,6 +136,8 @@ udp_snat_handler(struct sk_buff *skb,
return 0 ;
if ( unlikely ( cp - > app ! = NULL ) ) {
int ret ;
/* Some checks before mangling */
if ( pp - > csum_check & & ! pp - > csum_check ( cp - > af , skb , pp ) )
return 0 ;
@ -142,8 +145,13 @@ udp_snat_handler(struct sk_buff *skb,
/*
* Call application helper if needed
*/
if ( ! ip_vs_app_pkt_out ( cp , skb ) )
if ( ! ( ret = ip_vs_app_pkt_out ( cp , skb ) ) )
return 0 ;
/* ret=2: csum update is needed after payload mangling */
if ( ret = = 1 )
oldlen = skb - > len - udphoff ;
else
payload_csum = 1 ;
}
udph = ( void * ) skb_network_header ( skb ) + udphoff ;
@ -156,12 +164,13 @@ udp_snat_handler(struct sk_buff *skb,
udp_partial_csum_update ( cp - > af , udph , & cp - > daddr , & cp - > vaddr ,
htons ( oldlen ) ,
htons ( skb - > len - udphoff ) ) ;
} else if ( ! cp - > app & & ( udph - > check ! = 0 ) ) {
} else if ( ! payload_csum & & ( udph - > check ! = 0 ) ) {
/* Only port and addr are changed, do fast csum update */
udp_fast_csum_update ( cp - > af , udph , & cp - > daddr , & cp - > vaddr ,
cp - > dport , cp - > vport ) ;
if ( skb - > ip_summed = = CHECKSUM_COMPLETE )
skb - > ip_summed = CHECKSUM_NONE ;
skb - > ip_summed = ( cp - > app & & pp - > csum_check ) ?
CHECKSUM_UNNECESSARY : CHECKSUM_NONE ;
} else {
/* full checksum calculation */
udph - > check = 0 ;
@ -181,6 +190,7 @@ udp_snat_handler(struct sk_buff *skb,
skb - > csum ) ;
if ( udph - > check = = 0 )
udph - > check = CSUM_MANGLED_0 ;
skb - > ip_summed = CHECKSUM_UNNECESSARY ;
IP_VS_DBG ( 11 , " O-pkt: %s O-csum=%d (+%zd) \n " ,
pp - > name , udph - > check ,
( char * ) & ( udph - > check ) - ( char * ) udph ) ;
@ -196,6 +206,7 @@ udp_dnat_handler(struct sk_buff *skb,
struct udphdr * udph ;
unsigned int udphoff ;
int oldlen ;
int payload_csum = 0 ;
# ifdef CONFIG_IP_VS_IPV6
if ( cp - > af = = AF_INET6 )
@ -210,6 +221,8 @@ udp_dnat_handler(struct sk_buff *skb,
return 0 ;
if ( unlikely ( cp - > app ! = NULL ) ) {
int ret ;
/* Some checks before mangling */
if ( pp - > csum_check & & ! pp - > csum_check ( cp - > af , skb , pp ) )
return 0 ;
@ -218,8 +231,13 @@ udp_dnat_handler(struct sk_buff *skb,
* Attempt ip_vs_app call .
* It will fix ip_vs_conn
*/
if ( ! ip_vs_app_pkt_in ( cp , skb ) )
if ( ! ( ret = ip_vs_app_pkt_in ( cp , skb ) ) )
return 0 ;
/* ret=2: csum update is needed after payload mangling */
if ( ret = = 1 )
oldlen = skb - > len - udphoff ;
else
payload_csum = 1 ;
}
udph = ( void * ) skb_network_header ( skb ) + udphoff ;
@ -232,12 +250,13 @@ udp_dnat_handler(struct sk_buff *skb,
udp_partial_csum_update ( cp - > af , udph , & cp - > vaddr , & cp - > daddr ,
htons ( oldlen ) ,
htons ( skb - > len - udphoff ) ) ;
} else if ( ! cp - > app & & ( udph - > check ! = 0 ) ) {
} else if ( ! payload_csum & & ( udph - > check ! = 0 ) ) {
/* Only port and addr are changed, do fast csum update */
udp_fast_csum_update ( cp - > af , udph , & cp - > vaddr , & cp - > daddr ,
cp - > vport , cp - > dport ) ;
if ( skb - > ip_summed = = CHECKSUM_COMPLETE )
skb - > ip_summed = CHECKSUM_NONE ;
skb - > ip_summed = ( cp - > app & & pp - > csum_check ) ?
CHECKSUM_UNNECESSARY : CHECKSUM_NONE ;
} else {
/* full checksum calculation */
udph - > check = 0 ;