forked from mirrors/linux
		
	[AF_PACKET]: Add option to return orig_dev to userspace.
Add a packet socket option to allow the orig_dev index to be returned to userspace when passing traffic through a decapsulated device, such as the bonding driver. This is very useful for layer 2 traffic being able to report which physical device actually received the traffic, instead of having the encapsulating device hide that information. The new option is called PACKET_ORIGDEV. Signed-off-by: Peter P. Waskiewicz Jr. <peter.p.waskiewicz.jr@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									1370b5a59b
								
							
						
					
					
						commit
						80feaacb8a
					
				
					 2 changed files with 30 additions and 3 deletions
				
			
		|  | @ -42,6 +42,7 @@ struct sockaddr_ll | ||||||
| #define PACKET_STATISTICS		6 | #define PACKET_STATISTICS		6 | ||||||
| #define PACKET_COPY_THRESH		7 | #define PACKET_COPY_THRESH		7 | ||||||
| #define PACKET_AUXDATA			8 | #define PACKET_AUXDATA			8 | ||||||
|  | #define PACKET_ORIGDEV			9 | ||||||
| 
 | 
 | ||||||
| struct tpacket_stats | struct tpacket_stats | ||||||
| { | { | ||||||
|  |  | ||||||
|  | @ -201,7 +201,8 @@ struct packet_sock { | ||||||
| 	struct packet_type	prot_hook; | 	struct packet_type	prot_hook; | ||||||
| 	spinlock_t		bind_lock; | 	spinlock_t		bind_lock; | ||||||
| 	unsigned int		running:1,	/* prot_hook is attached*/ | 	unsigned int		running:1,	/* prot_hook is attached*/ | ||||||
| 				auxdata:1; | 				auxdata:1, | ||||||
|  | 				origdev:1; | ||||||
| 	int			ifindex;	/* bound device		*/ | 	int			ifindex;	/* bound device		*/ | ||||||
| 	__be16			num; | 	__be16			num; | ||||||
| #ifdef CONFIG_PACKET_MULTICAST | #ifdef CONFIG_PACKET_MULTICAST | ||||||
|  | @ -528,7 +529,10 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet | ||||||
| 	sll->sll_hatype = dev->type; | 	sll->sll_hatype = dev->type; | ||||||
| 	sll->sll_protocol = skb->protocol; | 	sll->sll_protocol = skb->protocol; | ||||||
| 	sll->sll_pkttype = skb->pkt_type; | 	sll->sll_pkttype = skb->pkt_type; | ||||||
| 	sll->sll_ifindex = dev->ifindex; | 	if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST) | ||||||
|  | 		sll->sll_ifindex = orig_dev->ifindex; | ||||||
|  | 	else | ||||||
|  | 		sll->sll_ifindex = dev->ifindex; | ||||||
| 	sll->sll_halen = 0; | 	sll->sll_halen = 0; | ||||||
| 
 | 
 | ||||||
| 	if (dev->hard_header_parse) | 	if (dev->hard_header_parse) | ||||||
|  | @ -673,7 +677,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe | ||||||
| 	sll->sll_hatype = dev->type; | 	sll->sll_hatype = dev->type; | ||||||
| 	sll->sll_protocol = skb->protocol; | 	sll->sll_protocol = skb->protocol; | ||||||
| 	sll->sll_pkttype = skb->pkt_type; | 	sll->sll_pkttype = skb->pkt_type; | ||||||
| 	sll->sll_ifindex = dev->ifindex; | 	if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST) | ||||||
|  | 		sll->sll_ifindex = orig_dev->ifindex; | ||||||
|  | 	else | ||||||
|  | 		sll->sll_ifindex = dev->ifindex; | ||||||
| 
 | 
 | ||||||
| 	h->tp_status = status; | 	h->tp_status = status; | ||||||
| 	smp_mb(); | 	smp_mb(); | ||||||
|  | @ -1413,6 +1420,18 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv | ||||||
| 		po->auxdata = !!val; | 		po->auxdata = !!val; | ||||||
| 		return 0; | 		return 0; | ||||||
| 	} | 	} | ||||||
|  | 	case PACKET_ORIGDEV: | ||||||
|  | 	{ | ||||||
|  | 		int val; | ||||||
|  | 
 | ||||||
|  | 		if (optlen < sizeof(val)) | ||||||
|  | 			return -EINVAL; | ||||||
|  | 		if (copy_from_user(&val, optval, sizeof(val))) | ||||||
|  | 			return -EFAULT; | ||||||
|  | 
 | ||||||
|  | 		po->origdev = !!val; | ||||||
|  | 		return 0; | ||||||
|  | 	} | ||||||
| 	default: | 	default: | ||||||
| 		return -ENOPROTOOPT; | 		return -ENOPROTOOPT; | ||||||
| 	} | 	} | ||||||
|  | @ -1454,6 +1473,13 @@ static int packet_getsockopt(struct socket *sock, int level, int optname, | ||||||
| 			len = sizeof(int); | 			len = sizeof(int); | ||||||
| 		val = po->auxdata; | 		val = po->auxdata; | ||||||
| 
 | 
 | ||||||
|  | 		data = &val; | ||||||
|  | 		break; | ||||||
|  | 	case PACKET_ORIGDEV: | ||||||
|  | 		if (len > sizeof(int)) | ||||||
|  | 			len = sizeof(int); | ||||||
|  | 		val = po->origdev; | ||||||
|  | 
 | ||||||
| 		data = &val; | 		data = &val; | ||||||
| 		break; | 		break; | ||||||
| 	default: | 	default: | ||||||
|  |  | ||||||
		Loading…
	
		Reference in a new issue
	
	 Peter P. Waskiewicz Jr
						Peter P. Waskiewicz Jr