aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet/af_packet.c
diff options
context:
space:
mode:
authorPeter P. Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>2007-04-20 19:05:39 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2007-04-26 01:29:14 -0400
commit80feaacb8a6400a9540a961b6743c69a5896b937 (patch)
treea4f07e635de521f5e283e0f4081923a98c0256d5 /net/packet/af_packet.c
parent1370b5a59b941ac3873b5e8614d496e9f481d670 (diff)
[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>
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r--net/packet/af_packet.c32
1 files changed, 29 insertions, 3 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 36388b2f32f9..02e401cd683f 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -201,7 +201,8 @@ struct packet_sock {
201 struct packet_type prot_hook; 201 struct packet_type prot_hook;
202 spinlock_t bind_lock; 202 spinlock_t bind_lock;
203 unsigned int running:1, /* prot_hook is attached*/ 203 unsigned int running:1, /* prot_hook is attached*/
204 auxdata:1; 204 auxdata:1,
205 origdev:1;
205 int ifindex; /* bound device */ 206 int ifindex; /* bound device */
206 __be16 num; 207 __be16 num;
207#ifdef CONFIG_PACKET_MULTICAST 208#ifdef CONFIG_PACKET_MULTICAST
@@ -528,7 +529,10 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
528 sll->sll_hatype = dev->type; 529 sll->sll_hatype = dev->type;
529 sll->sll_protocol = skb->protocol; 530 sll->sll_protocol = skb->protocol;
530 sll->sll_pkttype = skb->pkt_type; 531 sll->sll_pkttype = skb->pkt_type;
531 sll->sll_ifindex = dev->ifindex; 532 if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST)
533 sll->sll_ifindex = orig_dev->ifindex;
534 else
535 sll->sll_ifindex = dev->ifindex;
532 sll->sll_halen = 0; 536 sll->sll_halen = 0;
533 537
534 if (dev->hard_header_parse) 538 if (dev->hard_header_parse)
@@ -673,7 +677,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
673 sll->sll_hatype = dev->type; 677 sll->sll_hatype = dev->type;
674 sll->sll_protocol = skb->protocol; 678 sll->sll_protocol = skb->protocol;
675 sll->sll_pkttype = skb->pkt_type; 679 sll->sll_pkttype = skb->pkt_type;
676 sll->sll_ifindex = dev->ifindex; 680 if (unlikely(po->origdev) && skb->pkt_type == PACKET_HOST)
681 sll->sll_ifindex = orig_dev->ifindex;
682 else
683 sll->sll_ifindex = dev->ifindex;
677 684
678 h->tp_status = status; 685 h->tp_status = status;
679 smp_mb(); 686 smp_mb();
@@ -1413,6 +1420,18 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
1413 po->auxdata = !!val; 1420 po->auxdata = !!val;
1414 return 0; 1421 return 0;
1415 } 1422 }
1423 case PACKET_ORIGDEV:
1424 {
1425 int val;
1426
1427 if (optlen < sizeof(val))
1428 return -EINVAL;
1429 if (copy_from_user(&val, optval, sizeof(val)))
1430 return -EFAULT;
1431
1432 po->origdev = !!val;
1433 return 0;
1434 }
1416 default: 1435 default:
1417 return -ENOPROTOOPT; 1436 return -ENOPROTOOPT;
1418 } 1437 }
@@ -1456,6 +1475,13 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
1456 1475
1457 data = &val; 1476 data = &val;
1458 break; 1477 break;
1478 case PACKET_ORIGDEV:
1479 if (len > sizeof(int))
1480 len = sizeof(int);
1481 val = po->origdev;
1482
1483 data = &val;
1484 break;
1459 default: 1485 default:
1460 return -ENOPROTOOPT; 1486 return -ENOPROTOOPT;
1461 } 1487 }