aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet/af_packet.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 00:04:44 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-21 00:04:44 -0400
commitf8965467f366fd18f01feafb5db10512d7b4422c (patch)
tree3706a9cd779859271ca61b85c63a1bc3f82d626e /net/packet/af_packet.c
parenta26272e5200765691e67d6780e52b32498fdb659 (diff)
parent2ec8c6bb5d8f3a62a79f463525054bae1e3d4487 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next-2.6: (1674 commits) qlcnic: adding co maintainer ixgbe: add support for active DA cables ixgbe: dcb, do not tag tc_prio_control frames ixgbe: fix ixgbe_tx_is_paused logic ixgbe: always enable vlan strip/insert when DCB is enabled ixgbe: remove some redundant code in setting FCoE FIP filter ixgbe: fix wrong offset to fc_frame_header in ixgbe_fcoe_ddp ixgbe: fix header len when unsplit packet overflows to data buffer ipv6: Never schedule DAD timer on dead address ipv6: Use POSTDAD state ipv6: Use state_lock to protect ifa state ipv6: Replace inet6_ifaddr->dead with state cxgb4: notify upper drivers if the device is already up when they load cxgb4: keep interrupts available when the ports are brought down cxgb4: fix initial addition of MAC address cnic: Return SPQ credit to bnx2x after ring setup and shutdown. cnic: Convert cnic_local_flags to atomic ops. can: Fix SJA1000 command register writes on SMP systems bridge: fix build for CONFIG_SYSFS disabled ARCNET: Limit com20020 PCI ID matches for SOHARD cards ... Fix up various conflicts with pcmcia tree drivers/net/ {pcmcia/3c589_cs.c, wireless/orinoco/orinoco_cs.c and wireless/orinoco/spectrum_cs.c} and feature removal (Documentation/feature-removal-schedule.txt). Also fix a non-content conflict due to pm_qos_requirement getting renamed in the PM tree (now pm_qos_request) in net/mac80211/scan.c
Diffstat (limited to 'net/packet/af_packet.c')
-rw-r--r--net/packet/af_packet.c69
1 files changed, 64 insertions, 5 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 243946d4809d..2078a277e06b 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -82,6 +82,7 @@
82#include <linux/mutex.h> 82#include <linux/mutex.h>
83#include <linux/if_vlan.h> 83#include <linux/if_vlan.h>
84#include <linux/virtio_net.h> 84#include <linux/virtio_net.h>
85#include <linux/errqueue.h>
85 86
86#ifdef CONFIG_INET 87#ifdef CONFIG_INET
87#include <net/inet_common.h> 88#include <net/inet_common.h>
@@ -315,6 +316,8 @@ static inline struct packet_sock *pkt_sk(struct sock *sk)
315 316
316static void packet_sock_destruct(struct sock *sk) 317static void packet_sock_destruct(struct sock *sk)
317{ 318{
319 skb_queue_purge(&sk->sk_error_queue);
320
318 WARN_ON(atomic_read(&sk->sk_rmem_alloc)); 321 WARN_ON(atomic_read(&sk->sk_rmem_alloc));
319 WARN_ON(atomic_read(&sk->sk_wmem_alloc)); 322 WARN_ON(atomic_read(&sk->sk_wmem_alloc));
320 323
@@ -483,6 +486,9 @@ retry:
483 skb->dev = dev; 486 skb->dev = dev;
484 skb->priority = sk->sk_priority; 487 skb->priority = sk->sk_priority;
485 skb->mark = sk->sk_mark; 488 skb->mark = sk->sk_mark;
489 err = sock_tx_timestamp(msg, sk, skb_tx(skb));
490 if (err < 0)
491 goto out_unlock;
486 492
487 dev_queue_xmit(skb); 493 dev_queue_xmit(skb);
488 rcu_read_unlock(); 494 rcu_read_unlock();
@@ -1188,6 +1194,9 @@ static int packet_snd(struct socket *sock,
1188 err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len); 1194 err = skb_copy_datagram_from_iovec(skb, offset, msg->msg_iov, 0, len);
1189 if (err) 1195 if (err)
1190 goto out_free; 1196 goto out_free;
1197 err = sock_tx_timestamp(msg, sk, skb_tx(skb));
1198 if (err < 0)
1199 goto out_free;
1191 1200
1192 skb->protocol = proto; 1201 skb->protocol = proto;
1193 skb->dev = dev; 1202 skb->dev = dev;
@@ -1487,6 +1496,51 @@ out:
1487 return err; 1496 return err;
1488} 1497}
1489 1498
1499static int packet_recv_error(struct sock *sk, struct msghdr *msg, int len)
1500{
1501 struct sock_exterr_skb *serr;
1502 struct sk_buff *skb, *skb2;
1503 int copied, err;
1504
1505 err = -EAGAIN;
1506 skb = skb_dequeue(&sk->sk_error_queue);
1507 if (skb == NULL)
1508 goto out;
1509
1510 copied = skb->len;
1511 if (copied > len) {
1512 msg->msg_flags |= MSG_TRUNC;
1513 copied = len;
1514 }
1515 err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
1516 if (err)
1517 goto out_free_skb;
1518
1519 sock_recv_timestamp(msg, sk, skb);
1520
1521 serr = SKB_EXT_ERR(skb);
1522 put_cmsg(msg, SOL_PACKET, PACKET_TX_TIMESTAMP,
1523 sizeof(serr->ee), &serr->ee);
1524
1525 msg->msg_flags |= MSG_ERRQUEUE;
1526 err = copied;
1527
1528 /* Reset and regenerate socket error */
1529 spin_lock_bh(&sk->sk_error_queue.lock);
1530 sk->sk_err = 0;
1531 if ((skb2 = skb_peek(&sk->sk_error_queue)) != NULL) {
1532 sk->sk_err = SKB_EXT_ERR(skb2)->ee.ee_errno;
1533 spin_unlock_bh(&sk->sk_error_queue.lock);
1534 sk->sk_error_report(sk);
1535 } else
1536 spin_unlock_bh(&sk->sk_error_queue.lock);
1537
1538out_free_skb:
1539 kfree_skb(skb);
1540out:
1541 return err;
1542}
1543
1490/* 1544/*
1491 * Pull a packet from our receive queue and hand it to the user. 1545 * Pull a packet from our receive queue and hand it to the user.
1492 * If necessary we block. 1546 * If necessary we block.
@@ -1502,7 +1556,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
1502 int vnet_hdr_len = 0; 1556 int vnet_hdr_len = 0;
1503 1557
1504 err = -EINVAL; 1558 err = -EINVAL;
1505 if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT)) 1559 if (flags & ~(MSG_PEEK|MSG_DONTWAIT|MSG_TRUNC|MSG_CMSG_COMPAT|MSG_ERRQUEUE))
1506 goto out; 1560 goto out;
1507 1561
1508#if 0 1562#if 0
@@ -1511,6 +1565,11 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
1511 return -ENODEV; 1565 return -ENODEV;
1512#endif 1566#endif
1513 1567
1568 if (flags & MSG_ERRQUEUE) {
1569 err = packet_recv_error(sk, msg, len);
1570 goto out;
1571 }
1572
1514 /* 1573 /*
1515 * Call the generic datagram receiver. This handles all sorts 1574 * Call the generic datagram receiver. This handles all sorts
1516 * of horrible races and re-entrancy so we can forget about it 1575 * of horrible races and re-entrancy so we can forget about it
@@ -1692,9 +1751,9 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
1692 if (i->alen != dev->addr_len) 1751 if (i->alen != dev->addr_len)
1693 return -EINVAL; 1752 return -EINVAL;
1694 if (what > 0) 1753 if (what > 0)
1695 return dev_mc_add(dev, i->addr, i->alen, 0); 1754 return dev_mc_add(dev, i->addr);
1696 else 1755 else
1697 return dev_mc_delete(dev, i->addr, i->alen, 0); 1756 return dev_mc_del(dev, i->addr);
1698 break; 1757 break;
1699 case PACKET_MR_PROMISC: 1758 case PACKET_MR_PROMISC:
1700 return dev_set_promiscuity(dev, what); 1759 return dev_set_promiscuity(dev, what);
@@ -1706,9 +1765,9 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
1706 if (i->alen != dev->addr_len) 1765 if (i->alen != dev->addr_len)
1707 return -EINVAL; 1766 return -EINVAL;
1708 if (what > 0) 1767 if (what > 0)
1709 return dev_unicast_add(dev, i->addr); 1768 return dev_uc_add(dev, i->addr);
1710 else 1769 else
1711 return dev_unicast_delete(dev, i->addr); 1770 return dev_uc_del(dev, i->addr);
1712 break; 1771 break;
1713 default: 1772 default:
1714 break; 1773 break;