forked from mirrors/linux
		
	gro: Add internal interfaces for VLAN
Previously GRO's only entry point from the outside is through napi_gro_receive and napi_gro_frags. These interfaces are for device drivers. This patch rearranges things to provide a new set of interfaces for VLANs. These interfaces are for internal use only. The VLAN code itself can then provide a set of entry points for device drivers. Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									ff5bfc3584
								
							
						
					
					
						commit
						96e93eab20
					
				
					 2 changed files with 65 additions and 23 deletions
				
			
		| 
						 | 
					@ -1373,8 +1373,14 @@ extern int		netif_rx_ni(struct sk_buff *skb);
 | 
				
			||||||
#define HAVE_NETIF_RECEIVE_SKB 1
 | 
					#define HAVE_NETIF_RECEIVE_SKB 1
 | 
				
			||||||
extern int		netif_receive_skb(struct sk_buff *skb);
 | 
					extern int		netif_receive_skb(struct sk_buff *skb);
 | 
				
			||||||
extern void		napi_gro_flush(struct napi_struct *napi);
 | 
					extern void		napi_gro_flush(struct napi_struct *napi);
 | 
				
			||||||
 | 
					extern int		dev_gro_receive(struct napi_struct *napi,
 | 
				
			||||||
 | 
										struct sk_buff *skb);
 | 
				
			||||||
extern int		napi_gro_receive(struct napi_struct *napi,
 | 
					extern int		napi_gro_receive(struct napi_struct *napi,
 | 
				
			||||||
					 struct sk_buff *skb);
 | 
										 struct sk_buff *skb);
 | 
				
			||||||
 | 
					extern void		napi_reuse_skb(struct napi_struct *napi,
 | 
				
			||||||
 | 
									       struct sk_buff *skb);
 | 
				
			||||||
 | 
					extern struct sk_buff *	napi_fraginfo_skb(struct napi_struct *napi,
 | 
				
			||||||
 | 
										  struct napi_gro_fraginfo *info);
 | 
				
			||||||
extern int		napi_gro_frags(struct napi_struct *napi,
 | 
					extern int		napi_gro_frags(struct napi_struct *napi,
 | 
				
			||||||
				       struct napi_gro_fraginfo *info);
 | 
									       struct napi_gro_fraginfo *info);
 | 
				
			||||||
extern void		netif_nit_deliver(struct sk_buff *skb);
 | 
					extern void		netif_nit_deliver(struct sk_buff *skb);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2387,7 +2387,7 @@ void napi_gro_flush(struct napi_struct *napi)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(napi_gro_flush);
 | 
					EXPORT_SYMBOL(napi_gro_flush);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 | 
					int dev_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct sk_buff **pp = NULL;
 | 
						struct sk_buff **pp = NULL;
 | 
				
			||||||
	struct packet_type *ptype;
 | 
						struct packet_type *ptype;
 | 
				
			||||||
| 
						 | 
					@ -2417,11 +2417,14 @@ static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (p = napi->gro_list; p; p = p->next) {
 | 
							for (p = napi->gro_list; p; p = p->next) {
 | 
				
			||||||
			count++;
 | 
								count++;
 | 
				
			||||||
			NAPI_GRO_CB(p)->same_flow =
 | 
					
 | 
				
			||||||
				p->mac_len == mac_len &&
 | 
								if (!NAPI_GRO_CB(p)->same_flow)
 | 
				
			||||||
				!memcmp(skb_mac_header(p), skb_mac_header(skb),
 | 
									continue;
 | 
				
			||||||
					mac_len);
 | 
					
 | 
				
			||||||
			NAPI_GRO_CB(p)->flush = 0;
 | 
								if (p->mac_len != mac_len ||
 | 
				
			||||||
 | 
								    memcmp(skb_mac_header(p), skb_mac_header(skb),
 | 
				
			||||||
 | 
									   mac_len))
 | 
				
			||||||
 | 
									NAPI_GRO_CB(p)->same_flow = 0;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		pp = ptype->gro_receive(&napi->gro_list, skb);
 | 
							pp = ptype->gro_receive(&napi->gro_list, skb);
 | 
				
			||||||
| 
						 | 
					@ -2463,6 +2466,19 @@ static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 | 
				
			||||||
normal:
 | 
					normal:
 | 
				
			||||||
	return -1;
 | 
						return -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(dev_gro_receive);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int __napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sk_buff *p;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (p = napi->gro_list; p; p = p->next) {
 | 
				
			||||||
 | 
							NAPI_GRO_CB(p)->same_flow = 1;
 | 
				
			||||||
 | 
							NAPI_GRO_CB(p)->flush = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dev_gro_receive(napi, skb);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 | 
					int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -2479,11 +2495,26 @@ int napi_gro_receive(struct napi_struct *napi, struct sk_buff *skb)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL(napi_gro_receive);
 | 
					EXPORT_SYMBOL(napi_gro_receive);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info)
 | 
					void napi_reuse_skb(struct napi_struct *napi, struct sk_buff *skb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						skb_shinfo(skb)->nr_frags = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						skb->len -= skb->data_len;
 | 
				
			||||||
 | 
						skb->truesize -= skb->data_len;
 | 
				
			||||||
 | 
						skb->data_len = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__skb_pull(skb, skb_headlen(skb));
 | 
				
			||||||
 | 
						skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						napi->skb = skb;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(napi_reuse_skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct sk_buff *napi_fraginfo_skb(struct napi_struct *napi,
 | 
				
			||||||
 | 
									  struct napi_gro_fraginfo *info)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct net_device *dev = napi->dev;
 | 
						struct net_device *dev = napi->dev;
 | 
				
			||||||
	struct sk_buff *skb = napi->skb;
 | 
						struct sk_buff *skb = napi->skb;
 | 
				
			||||||
	int err = NET_RX_DROP;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	napi->skb = NULL;
 | 
						napi->skb = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2503,16 +2534,31 @@ int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info)
 | 
				
			||||||
	skb->len += info->len;
 | 
						skb->len += info->len;
 | 
				
			||||||
	skb->truesize += info->len;
 | 
						skb->truesize += info->len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!pskb_may_pull(skb, ETH_HLEN))
 | 
						if (!pskb_may_pull(skb, ETH_HLEN)) {
 | 
				
			||||||
		goto reuse;
 | 
							napi_reuse_skb(napi, skb);
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
	err = NET_RX_SUCCESS;
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	skb->protocol = eth_type_trans(skb, dev);
 | 
						skb->protocol = eth_type_trans(skb, dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	skb->ip_summed = info->ip_summed;
 | 
						skb->ip_summed = info->ip_summed;
 | 
				
			||||||
	skb->csum = info->csum;
 | 
						skb->csum = info->csum;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
 | 
						return skb;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					EXPORT_SYMBOL(napi_fraginfo_skb);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct sk_buff *skb = napi_fraginfo_skb(napi, info);
 | 
				
			||||||
 | 
						int err = NET_RX_DROP;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (!skb)
 | 
				
			||||||
 | 
							goto out;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						err = NET_RX_SUCCESS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (__napi_gro_receive(napi, skb)) {
 | 
						switch (__napi_gro_receive(napi, skb)) {
 | 
				
			||||||
	case -1:
 | 
						case -1:
 | 
				
			||||||
		return netif_receive_skb(skb);
 | 
							return netif_receive_skb(skb);
 | 
				
			||||||
| 
						 | 
					@ -2521,17 +2567,7 @@ int napi_gro_frags(struct napi_struct *napi, struct napi_gro_fraginfo *info)
 | 
				
			||||||
		goto out;
 | 
							goto out;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
reuse:
 | 
						napi_reuse_skb(napi, skb);
 | 
				
			||||||
	skb_shinfo(skb)->nr_frags = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	skb->len -= skb->data_len;
 | 
					 | 
				
			||||||
	skb->truesize -= skb->data_len;
 | 
					 | 
				
			||||||
	skb->data_len = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	__skb_pull(skb, skb_headlen(skb));
 | 
					 | 
				
			||||||
	skb_reserve(skb, NET_IP_ALIGN - skb_headroom(skb));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	napi->skb = skb;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
out:
 | 
					out:
 | 
				
			||||||
	return err;
 | 
						return err;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue