@ -3603,6 +3603,28 @@ void napi_gro_flush(struct napi_struct *napi, bool flush_old)
}
EXPORT_SYMBOL ( napi_gro_flush ) ;
static void gro_list_prepare ( struct napi_struct * napi , struct sk_buff * skb )
{
struct sk_buff * p ;
unsigned int maclen = skb - > dev - > hard_header_len ;
for ( p = napi - > gro_list ; p ; p = p - > next ) {
unsigned long diffs ;
diffs = ( unsigned long ) p - > dev ^ ( unsigned long ) skb - > dev ;
diffs | = p - > vlan_tci ^ skb - > vlan_tci ;
if ( maclen = = ETH_HLEN )
diffs | = compare_ether_header ( skb_mac_header ( p ) ,
skb_gro_mac_header ( skb ) ) ;
else if ( ! diffs )
diffs = memcmp ( skb_mac_header ( p ) ,
skb_gro_mac_header ( skb ) ,
maclen ) ;
NAPI_GRO_CB ( p ) - > same_flow = ! diffs ;
NAPI_GRO_CB ( p ) - > flush = 0 ;
}
}
static enum gro_result dev_gro_receive ( struct napi_struct * napi , struct sk_buff * skb )
{
struct sk_buff * * pp = NULL ;
@ -3619,6 +3641,8 @@ static enum gro_result dev_gro_receive(struct napi_struct *napi, struct sk_buff
if ( skb_is_gso ( skb ) | | skb_has_frag_list ( skb ) )
goto normal ;
gro_list_prepare ( napi , skb ) ;
rcu_read_lock ( ) ;
list_for_each_entry_rcu ( ptype , head , list ) {
if ( ptype - > type ! = type | | ! ptype - > callbacks . gro_receive )
@ -3695,30 +3719,6 @@ normal:
goto pull ;
}
static inline gro_result_t
__napi_gro_receive ( struct napi_struct * napi , struct sk_buff * skb )
{
struct sk_buff * p ;
unsigned int maclen = skb - > dev - > hard_header_len ;
for ( p = napi - > gro_list ; p ; p = p - > next ) {
unsigned long diffs ;
diffs = ( unsigned long ) p - > dev ^ ( unsigned long ) skb - > dev ;
diffs | = p - > vlan_tci ^ skb - > vlan_tci ;
if ( maclen = = ETH_HLEN )
diffs | = compare_ether_header ( skb_mac_header ( p ) ,
skb_gro_mac_header ( skb ) ) ;
else if ( ! diffs )
diffs = memcmp ( skb_mac_header ( p ) ,
skb_gro_mac_header ( skb ) ,
maclen ) ;
NAPI_GRO_CB ( p ) - > same_flow = ! diffs ;
NAPI_GRO_CB ( p ) - > flush = 0 ;
}
return dev_gro_receive ( napi , skb ) ;
}
static gro_result_t napi_skb_finish ( gro_result_t ret , struct sk_buff * skb )
{
@ -3768,7 +3768,7 @@ gro_result_t napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
{
skb_gro_reset_offset ( skb ) ;
return napi_skb_finish ( __napi _gro_receive( napi , skb ) , skb ) ;
return napi_skb_finish ( dev _gro_receive( napi , skb ) , skb ) ;
}
EXPORT_SYMBOL ( napi_gro_receive ) ;
@ -3866,7 +3866,7 @@ gro_result_t napi_gro_frags(struct napi_struct *napi)
if ( ! skb )
return GRO_DROP ;
return napi_frags_finish ( napi , skb , __napi _gro_receive( napi , skb ) ) ;
return napi_frags_finish ( napi , skb , dev _gro_receive( napi , skb ) ) ;
}
EXPORT_SYMBOL ( napi_gro_frags ) ;