aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-07-20 20:43:29 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2008-07-20 20:43:29 -0400
commitdb6d8c7a4027b48d797b369a53f8470aaeed7063 (patch)
treee140c104a89abc2154e1f41a7db8ebecbb6fa0b4 /net/packet
parent3a533374283aea50eab3976d8a6d30532175f009 (diff)
parentfb65a7c091529bfffb1262515252c0d0f6241c5c (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (1232 commits) iucv: Fix bad merging. net_sched: Add size table for qdiscs net_sched: Add accessor function for packet length for qdiscs net_sched: Add qdisc_enqueue wrapper highmem: Export totalhigh_pages. ipv6 mcast: Omit redundant address family checks in ip6_mc_source(). net: Use standard structures for generic socket address structures. ipv6 netns: Make several "global" sysctl variables namespace aware. netns: Use net_eq() to compare net-namespaces for optimization. ipv6: remove unused macros from net/ipv6.h ipv6: remove unused parameter from ip6_ra_control tcp: fix kernel panic with listening_get_next tcp: Remove redundant checks when setting eff_sacks tcp: options clean up tcp: Fix MD5 signatures for non-linear skbs sctp: Update sctp global memory limit allocations. sctp: remove unnecessary byteshifting, calculate directly in big-endian sctp: Allow only 1 listening socket with SO_REUSEADDR sctp: Do not leak memory on multiple listen() calls sctp: Support ipv6only AF_INET6 sockets. ...
Diffstat (limited to 'net/packet')
-rw-r--r--net/packet/af_packet.c222
1 files changed, 182 insertions, 40 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 2cee87da4441..d56cae112dc8 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -5,8 +5,6 @@
5 * 5 *
6 * PACKET - implements raw packet sockets. 6 * PACKET - implements raw packet sockets.
7 * 7 *
8 * Version: $Id: af_packet.c,v 1.61 2002/02/08 03:57:19 davem Exp $
9 *
10 * Authors: Ross Biro 8 * Authors: Ross Biro
11 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> 9 * Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
12 * Alan Cox, <gw4pts@gw4pts.ampr.org> 10 * Alan Cox, <gw4pts@gw4pts.ampr.org>
@@ -188,6 +186,9 @@ struct packet_sock {
188 unsigned int pg_vec_order; 186 unsigned int pg_vec_order;
189 unsigned int pg_vec_pages; 187 unsigned int pg_vec_pages;
190 unsigned int pg_vec_len; 188 unsigned int pg_vec_len;
189 enum tpacket_versions tp_version;
190 unsigned int tp_hdrlen;
191 unsigned int tp_reserve;
191#endif 192#endif
192}; 193};
193 194
@@ -203,14 +204,52 @@ struct packet_skb_cb {
203 204
204#ifdef CONFIG_PACKET_MMAP 205#ifdef CONFIG_PACKET_MMAP
205 206
206static inline struct tpacket_hdr *packet_lookup_frame(struct packet_sock *po, unsigned int position) 207static void *packet_lookup_frame(struct packet_sock *po, unsigned int position,
208 int status)
207{ 209{
208 unsigned int pg_vec_pos, frame_offset; 210 unsigned int pg_vec_pos, frame_offset;
211 union {
212 struct tpacket_hdr *h1;
213 struct tpacket2_hdr *h2;
214 void *raw;
215 } h;
209 216
210 pg_vec_pos = position / po->frames_per_block; 217 pg_vec_pos = position / po->frames_per_block;
211 frame_offset = position % po->frames_per_block; 218 frame_offset = position % po->frames_per_block;
212 219
213 return (struct tpacket_hdr *)(po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size)); 220 h.raw = po->pg_vec[pg_vec_pos] + (frame_offset * po->frame_size);
221 switch (po->tp_version) {
222 case TPACKET_V1:
223 if (status != h.h1->tp_status ? TP_STATUS_USER :
224 TP_STATUS_KERNEL)
225 return NULL;
226 break;
227 case TPACKET_V2:
228 if (status != h.h2->tp_status ? TP_STATUS_USER :
229 TP_STATUS_KERNEL)
230 return NULL;
231 break;
232 }
233 return h.raw;
234}
235
236static void __packet_set_status(struct packet_sock *po, void *frame, int status)
237{
238 union {
239 struct tpacket_hdr *h1;
240 struct tpacket2_hdr *h2;
241 void *raw;
242 } h;
243
244 h.raw = frame;
245 switch (po->tp_version) {
246 case TPACKET_V1:
247 h.h1->tp_status = status;
248 break;
249 case TPACKET_V2:
250 h.h2->tp_status = status;
251 break;
252 }
214} 253}
215#endif 254#endif
216 255
@@ -553,14 +592,19 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
553 struct sock *sk; 592 struct sock *sk;
554 struct packet_sock *po; 593 struct packet_sock *po;
555 struct sockaddr_ll *sll; 594 struct sockaddr_ll *sll;
556 struct tpacket_hdr *h; 595 union {
596 struct tpacket_hdr *h1;
597 struct tpacket2_hdr *h2;
598 void *raw;
599 } h;
557 u8 * skb_head = skb->data; 600 u8 * skb_head = skb->data;
558 int skb_len = skb->len; 601 int skb_len = skb->len;
559 unsigned int snaplen, res; 602 unsigned int snaplen, res;
560 unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER; 603 unsigned long status = TP_STATUS_LOSING|TP_STATUS_USER;
561 unsigned short macoff, netoff; 604 unsigned short macoff, netoff, hdrlen;
562 struct sk_buff *copy_skb = NULL; 605 struct sk_buff *copy_skb = NULL;
563 struct timeval tv; 606 struct timeval tv;
607 struct timespec ts;
564 608
565 if (skb->pkt_type == PACKET_LOOPBACK) 609 if (skb->pkt_type == PACKET_LOOPBACK)
566 goto drop; 610 goto drop;
@@ -592,10 +636,13 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
592 snaplen = res; 636 snaplen = res;
593 637
594 if (sk->sk_type == SOCK_DGRAM) { 638 if (sk->sk_type == SOCK_DGRAM) {
595 macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16; 639 macoff = netoff = TPACKET_ALIGN(po->tp_hdrlen) + 16 +
640 po->tp_reserve;
596 } else { 641 } else {
597 unsigned maclen = skb_network_offset(skb); 642 unsigned maclen = skb_network_offset(skb);
598 netoff = TPACKET_ALIGN(TPACKET_HDRLEN + (maclen < 16 ? 16 : maclen)); 643 netoff = TPACKET_ALIGN(po->tp_hdrlen +
644 (maclen < 16 ? 16 : maclen)) +
645 po->tp_reserve;
599 macoff = netoff - maclen; 646 macoff = netoff - maclen;
600 } 647 }
601 648
@@ -618,9 +665,8 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
618 } 665 }
619 666
620 spin_lock(&sk->sk_receive_queue.lock); 667 spin_lock(&sk->sk_receive_queue.lock);
621 h = packet_lookup_frame(po, po->head); 668 h.raw = packet_lookup_frame(po, po->head, TP_STATUS_KERNEL);
622 669 if (!h.raw)
623 if (h->tp_status)
624 goto ring_is_full; 670 goto ring_is_full;
625 po->head = po->head != po->frame_max ? po->head+1 : 0; 671 po->head = po->head != po->frame_max ? po->head+1 : 0;
626 po->stats.tp_packets++; 672 po->stats.tp_packets++;
@@ -632,20 +678,41 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
632 status &= ~TP_STATUS_LOSING; 678 status &= ~TP_STATUS_LOSING;
633 spin_unlock(&sk->sk_receive_queue.lock); 679 spin_unlock(&sk->sk_receive_queue.lock);
634 680
635 skb_copy_bits(skb, 0, (u8*)h + macoff, snaplen); 681 skb_copy_bits(skb, 0, h.raw + macoff, snaplen);
636 682
637 h->tp_len = skb->len; 683 switch (po->tp_version) {
638 h->tp_snaplen = snaplen; 684 case TPACKET_V1:
639 h->tp_mac = macoff; 685 h.h1->tp_len = skb->len;
640 h->tp_net = netoff; 686 h.h1->tp_snaplen = snaplen;
641 if (skb->tstamp.tv64) 687 h.h1->tp_mac = macoff;
642 tv = ktime_to_timeval(skb->tstamp); 688 h.h1->tp_net = netoff;
643 else 689 if (skb->tstamp.tv64)
644 do_gettimeofday(&tv); 690 tv = ktime_to_timeval(skb->tstamp);
645 h->tp_sec = tv.tv_sec; 691 else
646 h->tp_usec = tv.tv_usec; 692 do_gettimeofday(&tv);
693 h.h1->tp_sec = tv.tv_sec;
694 h.h1->tp_usec = tv.tv_usec;
695 hdrlen = sizeof(*h.h1);
696 break;
697 case TPACKET_V2:
698 h.h2->tp_len = skb->len;
699 h.h2->tp_snaplen = snaplen;
700 h.h2->tp_mac = macoff;
701 h.h2->tp_net = netoff;
702 if (skb->tstamp.tv64)
703 ts = ktime_to_timespec(skb->tstamp);
704 else
705 getnstimeofday(&ts);
706 h.h2->tp_sec = ts.tv_sec;
707 h.h2->tp_nsec = ts.tv_nsec;
708 h.h2->tp_vlan_tci = skb->vlan_tci;
709 hdrlen = sizeof(*h.h2);
710 break;
711 default:
712 BUG();
713 }
647 714
648 sll = (struct sockaddr_ll*)((u8*)h + TPACKET_ALIGN(sizeof(*h))); 715 sll = h.raw + TPACKET_ALIGN(hdrlen);
649 sll->sll_halen = dev_parse_header(skb, sll->sll_addr); 716 sll->sll_halen = dev_parse_header(skb, sll->sll_addr);
650 sll->sll_family = AF_PACKET; 717 sll->sll_family = AF_PACKET;
651 sll->sll_hatype = dev->type; 718 sll->sll_hatype = dev->type;
@@ -656,14 +723,14 @@ static int tpacket_rcv(struct sk_buff *skb, struct net_device *dev, struct packe
656 else 723 else
657 sll->sll_ifindex = dev->ifindex; 724 sll->sll_ifindex = dev->ifindex;
658 725
659 h->tp_status = status; 726 __packet_set_status(po, h.raw, status);
660 smp_mb(); 727 smp_mb();
661 728
662 { 729 {
663 struct page *p_start, *p_end; 730 struct page *p_start, *p_end;
664 u8 *h_end = (u8 *)h + macoff + snaplen - 1; 731 u8 *h_end = h.raw + macoff + snaplen - 1;
665 732
666 p_start = virt_to_page(h); 733 p_start = virt_to_page(h.raw);
667 p_end = virt_to_page(h_end); 734 p_end = virt_to_page(h_end);
668 while (p_start <= p_end) { 735 while (p_start <= p_end) {
669 flush_dcache_page(p_start); 736 flush_dcache_page(p_start);
@@ -1109,6 +1176,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
1109 aux.tp_snaplen = skb->len; 1176 aux.tp_snaplen = skb->len;
1110 aux.tp_mac = 0; 1177 aux.tp_mac = 0;
1111 aux.tp_net = skb_network_offset(skb); 1178 aux.tp_net = skb_network_offset(skb);
1179 aux.tp_vlan_tci = skb->vlan_tci;
1112 1180
1113 put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux); 1181 put_cmsg(msg, SOL_PACKET, PACKET_AUXDATA, sizeof(aux), &aux);
1114 } 1182 }
@@ -1175,7 +1243,8 @@ static int packet_getname(struct socket *sock, struct sockaddr *uaddr,
1175 return 0; 1243 return 0;
1176} 1244}
1177 1245
1178static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int what) 1246static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
1247 int what)
1179{ 1248{
1180 switch (i->type) { 1249 switch (i->type) {
1181 case PACKET_MR_MULTICAST: 1250 case PACKET_MR_MULTICAST:
@@ -1185,13 +1254,14 @@ static void packet_dev_mc(struct net_device *dev, struct packet_mclist *i, int w
1185 dev_mc_delete(dev, i->addr, i->alen, 0); 1254 dev_mc_delete(dev, i->addr, i->alen, 0);
1186 break; 1255 break;
1187 case PACKET_MR_PROMISC: 1256 case PACKET_MR_PROMISC:
1188 dev_set_promiscuity(dev, what); 1257 return dev_set_promiscuity(dev, what);
1189 break; 1258 break;
1190 case PACKET_MR_ALLMULTI: 1259 case PACKET_MR_ALLMULTI:
1191 dev_set_allmulti(dev, what); 1260 return dev_set_allmulti(dev, what);
1192 break; 1261 break;
1193 default:; 1262 default:;
1194 } 1263 }
1264 return 0;
1195} 1265}
1196 1266
1197static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what) 1267static void packet_dev_mclist(struct net_device *dev, struct packet_mclist *i, int what)
@@ -1245,7 +1315,11 @@ static int packet_mc_add(struct sock *sk, struct packet_mreq_max *mreq)
1245 i->count = 1; 1315 i->count = 1;
1246 i->next = po->mclist; 1316 i->next = po->mclist;
1247 po->mclist = i; 1317 po->mclist = i;
1248 packet_dev_mc(dev, i, +1); 1318 err = packet_dev_mc(dev, i, 1);
1319 if (err) {
1320 po->mclist = i->next;
1321 kfree(i);
1322 }
1249 1323
1250done: 1324done:
1251 rtnl_unlock(); 1325 rtnl_unlock();
@@ -1358,6 +1432,38 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
1358 pkt_sk(sk)->copy_thresh = val; 1432 pkt_sk(sk)->copy_thresh = val;
1359 return 0; 1433 return 0;
1360 } 1434 }
1435 case PACKET_VERSION:
1436 {
1437 int val;
1438
1439 if (optlen != sizeof(val))
1440 return -EINVAL;
1441 if (po->pg_vec)
1442 return -EBUSY;
1443 if (copy_from_user(&val, optval, sizeof(val)))
1444 return -EFAULT;
1445 switch (val) {
1446 case TPACKET_V1:
1447 case TPACKET_V2:
1448 po->tp_version = val;
1449 return 0;
1450 default:
1451 return -EINVAL;
1452 }
1453 }
1454 case PACKET_RESERVE:
1455 {
1456 unsigned int val;
1457
1458 if (optlen != sizeof(val))
1459 return -EINVAL;
1460 if (po->pg_vec)
1461 return -EBUSY;
1462 if (copy_from_user(&val, optval, sizeof(val)))
1463 return -EFAULT;
1464 po->tp_reserve = val;
1465 return 0;
1466 }
1361#endif 1467#endif
1362 case PACKET_AUXDATA: 1468 case PACKET_AUXDATA:
1363 { 1469 {
@@ -1433,6 +1539,37 @@ static int packet_getsockopt(struct socket *sock, int level, int optname,
1433 1539
1434 data = &val; 1540 data = &val;
1435 break; 1541 break;
1542#ifdef CONFIG_PACKET_MMAP
1543 case PACKET_VERSION:
1544 if (len > sizeof(int))
1545 len = sizeof(int);
1546 val = po->tp_version;
1547 data = &val;
1548 break;
1549 case PACKET_HDRLEN:
1550 if (len > sizeof(int))
1551 len = sizeof(int);
1552 if (copy_from_user(&val, optval, len))
1553 return -EFAULT;
1554 switch (val) {
1555 case TPACKET_V1:
1556 val = sizeof(struct tpacket_hdr);
1557 break;
1558 case TPACKET_V2:
1559 val = sizeof(struct tpacket2_hdr);
1560 break;
1561 default:
1562 return -EINVAL;
1563 }
1564 data = &val;
1565 break;
1566 case PACKET_RESERVE:
1567 if (len > sizeof(unsigned int))
1568 len = sizeof(unsigned int);
1569 val = po->tp_reserve;
1570 data = &val;
1571 break;
1572#endif
1436 default: 1573 default:
1437 return -ENOPROTOOPT; 1574 return -ENOPROTOOPT;
1438 } 1575 }
@@ -1540,7 +1677,7 @@ static int packet_ioctl(struct socket *sock, unsigned int cmd,
1540 case SIOCGIFDSTADDR: 1677 case SIOCGIFDSTADDR:
1541 case SIOCSIFDSTADDR: 1678 case SIOCSIFDSTADDR:
1542 case SIOCSIFFLAGS: 1679 case SIOCSIFFLAGS:
1543 if (sock_net(sk) != &init_net) 1680 if (!net_eq(sock_net(sk), &init_net))
1544 return -ENOIOCTLCMD; 1681 return -ENOIOCTLCMD;
1545 return inet_dgram_ops.ioctl(sock, cmd, arg); 1682 return inet_dgram_ops.ioctl(sock, cmd, arg);
1546#endif 1683#endif
@@ -1566,11 +1703,8 @@ static unsigned int packet_poll(struct file * file, struct socket *sock,
1566 spin_lock_bh(&sk->sk_receive_queue.lock); 1703 spin_lock_bh(&sk->sk_receive_queue.lock);
1567 if (po->pg_vec) { 1704 if (po->pg_vec) {
1568 unsigned last = po->head ? po->head-1 : po->frame_max; 1705 unsigned last = po->head ? po->head-1 : po->frame_max;
1569 struct tpacket_hdr *h;
1570
1571 h = packet_lookup_frame(po, last);
1572 1706
1573 if (h->tp_status) 1707 if (packet_lookup_frame(po, last, TP_STATUS_USER))
1574 mask |= POLLIN | POLLRDNORM; 1708 mask |= POLLIN | POLLRDNORM;
1575 } 1709 }
1576 spin_unlock_bh(&sk->sk_receive_queue.lock); 1710 spin_unlock_bh(&sk->sk_receive_queue.lock);
@@ -1665,11 +1799,21 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
1665 if (unlikely(po->pg_vec)) 1799 if (unlikely(po->pg_vec))
1666 return -EBUSY; 1800 return -EBUSY;
1667 1801
1802 switch (po->tp_version) {
1803 case TPACKET_V1:
1804 po->tp_hdrlen = TPACKET_HDRLEN;
1805 break;
1806 case TPACKET_V2:
1807 po->tp_hdrlen = TPACKET2_HDRLEN;
1808 break;
1809 }
1810
1668 if (unlikely((int)req->tp_block_size <= 0)) 1811 if (unlikely((int)req->tp_block_size <= 0))
1669 return -EINVAL; 1812 return -EINVAL;
1670 if (unlikely(req->tp_block_size & (PAGE_SIZE - 1))) 1813 if (unlikely(req->tp_block_size & (PAGE_SIZE - 1)))
1671 return -EINVAL; 1814 return -EINVAL;
1672 if (unlikely(req->tp_frame_size < TPACKET_HDRLEN)) 1815 if (unlikely(req->tp_frame_size < po->tp_hdrlen +
1816 po->tp_reserve))
1673 return -EINVAL; 1817 return -EINVAL;
1674 if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1))) 1818 if (unlikely(req->tp_frame_size & (TPACKET_ALIGNMENT - 1)))
1675 return -EINVAL; 1819 return -EINVAL;
@@ -1688,13 +1832,11 @@ static int packet_set_ring(struct sock *sk, struct tpacket_req *req, int closing
1688 goto out; 1832 goto out;
1689 1833
1690 for (i = 0; i < req->tp_block_nr; i++) { 1834 for (i = 0; i < req->tp_block_nr; i++) {
1691 char *ptr = pg_vec[i]; 1835 void *ptr = pg_vec[i];
1692 struct tpacket_hdr *header;
1693 int k; 1836 int k;
1694 1837
1695 for (k = 0; k < po->frames_per_block; k++) { 1838 for (k = 0; k < po->frames_per_block; k++) {
1696 header = (struct tpacket_hdr *) ptr; 1839 __packet_set_status(po, ptr, TP_STATUS_KERNEL);
1697 header->tp_status = TP_STATUS_KERNEL;
1698 ptr += req->tp_frame_size; 1840 ptr += req->tp_frame_size;
1699 } 1841 }
1700 } 1842 }