forked from mirrors/linux
		
	af-packet: Use existing netdev reference for bound sockets.
This saves a network device lookup on each packet transmitted, for sockets that are bound to a network device. Signed-off-by: Ben Greear <greearb@candelatech.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									160ff18a07
								
							
						
					
					
						commit
						827d978037
					
				
					 1 changed files with 15 additions and 12 deletions
				
			
		|  | @ -974,7 +974,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | ||||||
| 	struct sk_buff *skb; | 	struct sk_buff *skb; | ||||||
| 	struct net_device *dev; | 	struct net_device *dev; | ||||||
| 	__be16 proto; | 	__be16 proto; | ||||||
| 	int ifindex, err, reserve = 0; | 	bool need_rls_dev = false; | ||||||
|  | 	int err, reserve = 0; | ||||||
| 	void *ph; | 	void *ph; | ||||||
| 	struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; | 	struct sockaddr_ll *saddr = (struct sockaddr_ll *)msg->msg_name; | ||||||
| 	int tp_len, size_max; | 	int tp_len, size_max; | ||||||
|  | @ -986,7 +987,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | ||||||
| 
 | 
 | ||||||
| 	err = -EBUSY; | 	err = -EBUSY; | ||||||
| 	if (saddr == NULL) { | 	if (saddr == NULL) { | ||||||
| 		ifindex	= po->ifindex; | 		dev = po->prot_hook.dev; | ||||||
| 		proto	= po->num; | 		proto	= po->num; | ||||||
| 		addr	= NULL; | 		addr	= NULL; | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -997,12 +998,12 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | ||||||
| 					+ offsetof(struct sockaddr_ll, | 					+ offsetof(struct sockaddr_ll, | ||||||
| 						sll_addr))) | 						sll_addr))) | ||||||
| 			goto out; | 			goto out; | ||||||
| 		ifindex	= saddr->sll_ifindex; |  | ||||||
| 		proto	= saddr->sll_protocol; | 		proto	= saddr->sll_protocol; | ||||||
| 		addr	= saddr->sll_addr; | 		addr	= saddr->sll_addr; | ||||||
|  | 		dev = dev_get_by_index(sock_net(&po->sk), saddr->sll_ifindex); | ||||||
|  | 		need_rls_dev = true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	dev = dev_get_by_index(sock_net(&po->sk), ifindex); |  | ||||||
| 	err = -ENXIO; | 	err = -ENXIO; | ||||||
| 	if (unlikely(dev == NULL)) | 	if (unlikely(dev == NULL)) | ||||||
| 		goto out; | 		goto out; | ||||||
|  | @ -1088,7 +1089,8 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg) | ||||||
| 	__packet_set_status(po, ph, status); | 	__packet_set_status(po, ph, status); | ||||||
| 	kfree_skb(skb); | 	kfree_skb(skb); | ||||||
| out_put: | out_put: | ||||||
| 	dev_put(dev); | 	if (need_rls_dev) | ||||||
|  | 		dev_put(dev); | ||||||
| out: | out: | ||||||
| 	mutex_unlock(&po->pg_vec_lock); | 	mutex_unlock(&po->pg_vec_lock); | ||||||
| 	return err; | 	return err; | ||||||
|  | @ -1126,8 +1128,9 @@ static int packet_snd(struct socket *sock, | ||||||
| 	struct sk_buff *skb; | 	struct sk_buff *skb; | ||||||
| 	struct net_device *dev; | 	struct net_device *dev; | ||||||
| 	__be16 proto; | 	__be16 proto; | ||||||
|  | 	bool need_rls_dev = false; | ||||||
| 	unsigned char *addr; | 	unsigned char *addr; | ||||||
| 	int ifindex, err, reserve = 0; | 	int err, reserve = 0; | ||||||
| 	struct virtio_net_hdr vnet_hdr = { 0 }; | 	struct virtio_net_hdr vnet_hdr = { 0 }; | ||||||
| 	int offset = 0; | 	int offset = 0; | ||||||
| 	int vnet_hdr_len; | 	int vnet_hdr_len; | ||||||
|  | @ -1139,7 +1142,7 @@ static int packet_snd(struct socket *sock, | ||||||
| 	 */ | 	 */ | ||||||
| 
 | 
 | ||||||
| 	if (saddr == NULL) { | 	if (saddr == NULL) { | ||||||
| 		ifindex	= po->ifindex; | 		dev = po->prot_hook.dev; | ||||||
| 		proto	= po->num; | 		proto	= po->num; | ||||||
| 		addr	= NULL; | 		addr	= NULL; | ||||||
| 	} else { | 	} else { | ||||||
|  | @ -1148,13 +1151,12 @@ static int packet_snd(struct socket *sock, | ||||||
| 			goto out; | 			goto out; | ||||||
| 		if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) | 		if (msg->msg_namelen < (saddr->sll_halen + offsetof(struct sockaddr_ll, sll_addr))) | ||||||
| 			goto out; | 			goto out; | ||||||
| 		ifindex	= saddr->sll_ifindex; |  | ||||||
| 		proto	= saddr->sll_protocol; | 		proto	= saddr->sll_protocol; | ||||||
| 		addr	= saddr->sll_addr; | 		addr	= saddr->sll_addr; | ||||||
|  | 		dev = dev_get_by_index(sock_net(sk), saddr->sll_ifindex); | ||||||
|  | 		need_rls_dev = true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
| 	dev = dev_get_by_index(sock_net(sk), ifindex); |  | ||||||
| 	err = -ENXIO; | 	err = -ENXIO; | ||||||
| 	if (dev == NULL) | 	if (dev == NULL) | ||||||
| 		goto out_unlock; | 		goto out_unlock; | ||||||
|  | @ -1285,14 +1287,15 @@ static int packet_snd(struct socket *sock, | ||||||
| 	if (err > 0 && (err = net_xmit_errno(err)) != 0) | 	if (err > 0 && (err = net_xmit_errno(err)) != 0) | ||||||
| 		goto out_unlock; | 		goto out_unlock; | ||||||
| 
 | 
 | ||||||
| 	dev_put(dev); | 	if (need_rls_dev) | ||||||
|  | 		dev_put(dev); | ||||||
| 
 | 
 | ||||||
| 	return len; | 	return len; | ||||||
| 
 | 
 | ||||||
| out_free: | out_free: | ||||||
| 	kfree_skb(skb); | 	kfree_skb(skb); | ||||||
| out_unlock: | out_unlock: | ||||||
| 	if (dev) | 	if (dev && need_rls_dev) | ||||||
| 		dev_put(dev); | 		dev_put(dev); | ||||||
| out: | out: | ||||||
| 	return err; | 	return err; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Ben Greear
						Ben Greear