aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet/af_packet.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r--net/packet/af_packet.c94
1 files changed, 62 insertions, 32 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 28d47e8f2873..02e401cd683f 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -114,22 +114,22 @@ On receive:
114----------- 114-----------
115 115
116Incoming, dev->hard_header!=NULL 116Incoming, dev->hard_header!=NULL
117 mac.raw -> ll header 117 mac_header -> ll header
118 data -> data 118 data -> data
119 119
120Outgoing, dev->hard_header!=NULL 120Outgoing, dev->hard_header!=NULL
121 mac.raw -> ll header 121 mac_header -> ll header
122 data -> ll header 122 data -> ll header
123 123
124Incoming, dev->hard_header==NULL 124Incoming, dev->hard_header==NULL
125 mac.raw -> UNKNOWN position. It is very likely, that it points to ll header. 125 mac_header -> UNKNOWN position. It is very likely, that it points to ll
126 PPP makes it, that is wrong, because introduce assymetry 126 header. PPP makes it, that is wrong, because introduce
127 between rx and tx paths. 127 assymetry between rx and tx paths.
128 data -> data 128 data -> data
129 129
130Outgoing, dev->hard_header==NULL 130Outgoing, dev->hard_header==NULL
131 mac.raw -> data. ll header is still not built! 131 mac_header -> data. ll header is still not built!
132 data -> data 132 data -> data
133 133
134Resume 134Resume
135 If dev->hard_header==NULL we are unlikely to restore sensible ll header. 135 If dev->hard_header==NULL we are unlikely to restore sensible ll header.
@@ -139,12 +139,12 @@ On transmit:
139------------ 139------------
140 140
141dev->hard_header != NULL 141dev->hard_header != NULL
142 mac.raw -> ll header 142 mac_header -> ll header
143 data -> ll header 143 data -> ll header
144 144
145dev->hard_header == NULL (ll header is added by device, we cannot control it) 145dev->hard_header == NULL (ll header is added by device, we cannot control it)
146 mac.raw -> data 146 mac_header -> data
147 data -> data 147 data -> data
148 148
149 We should set nh.raw on output to correct posistion, 149 We should set nh.raw on output to correct posistion,
150 packet classifier depends on it. 150 packet classifier depends on it.
@@ -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
@@ -284,7 +285,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct
284 * Incoming packets have ll header pulled, 285 * Incoming packets have ll header pulled,
285 * push it back. 286 * push it back.
286 * 287 *
287 * For outgoing ones skb->data == skb->mac.raw 288 * For outgoing ones skb->data == skb_mac_header(skb)
288 * so that this procedure is noop. 289 * so that this procedure is noop.
289 */ 290 */
290 291
@@ -303,7 +304,7 @@ static int packet_rcv_spkt(struct sk_buff *skb, struct net_device *dev, struct
303 304
304 spkt = &PACKET_SKB_CB(skb)->sa.pkt; 305 spkt = &PACKET_SKB_CB(skb)->sa.pkt;
305 306
306 skb_push(skb, skb->data-skb->mac.raw); 307 skb_push(skb, skb->data - skb_mac_header(skb));
307 308
308 /* 309 /*
309 * The SOCK_PACKET socket receives _all_ frames. 310 * The SOCK_PACKET socket receives _all_ frames.
@@ -401,14 +402,14 @@ static int packet_sendmsg_spkt(struct kiocb *iocb, struct socket *sock,
401 * notable one here. This should really be fixed at the driver level. 402 * notable one here. This should really be fixed at the driver level.
402 */ 403 */
403 skb_reserve(skb, LL_RESERVED_SPACE(dev)); 404 skb_reserve(skb, LL_RESERVED_SPACE(dev));
404 skb->nh.raw = skb->data; 405 skb_reset_network_header(skb);
405 406
406 /* Try to align data part correctly */ 407 /* Try to align data part correctly */
407 if (dev->hard_header) { 408 if (dev->hard_header) {
408 skb->data -= dev->hard_header_len; 409 skb->data -= dev->hard_header_len;
409 skb->tail -= dev->hard_header_len; 410 skb->tail -= dev->hard_header_len;
410 if (len < dev->hard_header_len) 411 if (len < dev->hard_header_len)
411 skb->nh.raw = skb->data; 412 skb_reset_network_header(skb);
412 } 413 }
413 414
414 /* Returns -EFAULT on error */ 415 /* Returns -EFAULT on error */
@@ -488,10 +489,10 @@ static int packet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet
488 never delivered to user. 489 never delivered to user.
489 */ 490 */
490 if (sk->sk_type != SOCK_DGRAM) 491 if (sk->sk_type != SOCK_DGRAM)
491 skb_push(skb, skb->data - skb->mac.raw); 492 skb_push(skb, skb->data - skb_mac_header(skb));
492 else if (skb->pkt_type == PACKET_OUTGOING) { 493 else if (skb->pkt_type == PACKET_OUTGOING) {
493 /* Special case: outgoing packets have ll header at head */ 494 /* Special case: outgoing packets have ll header at head */
494 skb_pull(skb, skb->nh.raw - skb->data); 495 skb_pull(skb, skb_network_offset(skb));
495 } 496 }
496 } 497 }
497 498
@@ -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)
@@ -582,6 +586,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
582 unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER; 586 unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER;
583 unsigned short macoff, netoff; 587 unsigned short macoff, netoff;
584 struct sk_buff *copy_skb = NULL; 588 struct sk_buff *copy_skb = NULL;
589 struct timeval tv;
585 590
586 if (skb->pkt_type == PACKET_LOOPBACK) 591 if (skb->pkt_type == PACKET_LOOPBACK)
587 goto drop; 592 goto drop;
@@ -591,10 +596,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
591 596
592 if (dev->hard_header) { 597 if (dev->hard_header) {
593 if (sk->sk_type != SOCK_DGRAM) 598 if (sk->sk_type != SOCK_DGRAM)
594 skb_push(skb, skb->data - skb->mac.raw); 599 skb_push(skb, skb->data - skb_mac_header(skb));
595 else if (skb->pkt_type == PACKET_OUTGOING) { 600 else if (skb->pkt_type == PACKET_OUTGOING) {
596 /* Special case: outgoing packets have ll header at head */ 601 /* Special case: outgoing packets have ll header at head */
597 skb_pull(skb, skb->nh.raw - skb->data); 602 skb_pull(skb, skb_network_offset(skb));
598 } 603 }
599 } 604 }
600 605
@@ -612,7 +617,7 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
612 if (sk->sk_type == SOCK_DGRAM) { 617 if (sk->sk_type == SOCK_DGRAM) {
613 macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16; 618 macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16;
614 } else { 619 } else {
615 unsigned maclen = skb->nh.raw - skb->data; 620 unsigned maclen = skb_network_offset(skb);
616 netoff = TPACKET_ALIGN(TPACKET_HDRLEN + (maclen < 16 ? 16 : maclen)); 621 netoff = TPACKET_ALIGN(TPACKET_HDRLEN + (maclen < 16 ? 16 : maclen));
617 macoff = netoff - maclen; 622 macoff = netoff - maclen;
618 } 623 }
@@ -656,12 +661,13 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
656 h->tp_snaplen = snaplen; 661 h->tp_snaplen = snaplen;
657 h->tp_mac = macoff; 662 h->tp_mac = macoff;
658 h->tp_net = netoff; 663 h->tp_net = netoff;
659 if (skb->tstamp.off_sec == 0) { 664 if (skb->tstamp.tv64 == 0) {
660 __net_timestamp(skb); 665 __net_timestamp(skb);
661 sock_enable_timestamp(sk); 666 sock_enable_timestamp(sk);
662 } 667 }
663 h->tp_sec = skb->tstamp.off_sec; 668 tv = ktime_to_timeval(skb->tstamp);
664 h->tp_usec = skb->tstamp.off_usec; 669 h->tp_sec = tv.tv_sec;
670 h->tp_usec = tv.tv_usec;
665 671
666 sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h))); 672 sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h)));
667 sll->sll_halen = 0; 673 sll->sll_halen = 0;
@@ -671,7 +677,10 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
671 sll->sll_hatype = dev->type; 677 sll->sll_hatype = dev->type;
672 sll->sll_protocol = skb->protocol; 678 sll->sll_protocol = skb->protocol;
673 sll->sll_pkttype = skb->pkt_type; 679 sll->sll_pkttype = skb->pkt_type;
674 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;
675 684
676 h->tp_status = status; 685 h->tp_status = status;
677 smp_mb(); 686 smp_mb();
@@ -766,14 +775,14 @@ static int packet_sendmsg(struct kiocb *iocb, struct socket *sock,
766 goto out_unlock; 775 goto out_unlock;
767 776
768 skb_reserve(skb, LL_RESERVED_SPACE(dev)); 777 skb_reserve(skb, LL_RESERVED_SPACE(dev));
769 skb->nh.raw = skb->data; 778 skb_reset_network_header(skb);
770 779
771 if (dev->hard_header) { 780 if (dev->hard_header) {
772 int res; 781 int res;
773 err = -EINVAL; 782 err = -EINVAL;
774 res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len); 783 res = dev->hard_header(skb, dev, ntohs(proto), addr, NULL, len);
775 if (sock->type != SOCK_DGRAM) { 784 if (sock->type != SOCK_DGRAM) {
776 skb->tail = skb->data; 785 skb_reset_tail_pointer(skb);
777 skb->len = 0; 786 skb->len = 0;
778 } else if (res < 0) 787 } else if (res < 0)
779 goto out_free; 788 goto out_free;
@@ -1143,7 +1152,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
1143 aux.tp_len = PACKET_SKB_CB(skb)->origlen; 1152 aux.tp_len = PACKET_SKB_CB(skb)->origlen;
1144 aux.tp_snaplen = skb->len; 1153 aux.tp_snaplen = skb->len;
1145 aux.tp_mac = 0; 1154 aux.tp_mac = 0;
1146 aux.tp_net = skb->nh.raw - skb->data; 1155 aux.tp_net = skb_network_offset(skb);
1147 1156
1148 put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); 1157 put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);
1149 } 1158 }
@@ -1411,6 +1420,18 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
1411 po->auxdata = !!val; 1420 po->auxdata = !!val;
1412 return 0; 1421 return 0;
1413 } 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 }
1414 default: 1435 default:
1415 return -ENOPROTOOPT; 1436 return -ENOPROTOOPT;
1416 } 1437 }
@@ -1454,6 +1475,13 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
1454 1475
1455 data = &val; 1476 data = &val;
1456 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;
1457 default: 1485 default:
1458 return -ENOPROTOOPT; 1486 return -ENOPROTOOPT;
1459 } 1487 }
@@ -1543,6 +1571,8 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
1543 } 1571 }
1544 case SIOCGSTAMP: 1572 case SIOCGSTAMP:
1545 return sock_get_timestamp(sk, (struct timeval __user *)arg); 1573 return sock_get_timestamp(sk, (struct timeval __user *)arg);
1574 case SIOCGSTAMPNS:
1575 return sock_get_timestampns(sk, (struct timespec __user *)arg);
1546 1576
1547#ifdef CONFIG_INET 1577#ifdef CONFIG_INET
1548 case SIOCADDRT: 1578 case SIOCADDRT: