aboutsummaryrefslogtreecommitdiffstats
path: root/net/packet
diff options
context:
space:
mode:
Diffstat (limited to 'net/packet')
-rw-r--r--net/packet/af_packet.c70
1 files changed, 65 insertions, 5 deletions
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 1612d417d10c..f162d59d8161 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -60,6 +60,7 @@
60#include <linux/wireless.h> 60#include <linux/wireless.h>
61#include <linux/kernel.h> 61#include <linux/kernel.h>
62#include <linux/kmod.h> 62#include <linux/kmod.h>
63#include <linux/slab.h>
63#include <net/net_namespace.h> 64#include <net/net_namespace.h>
64#include <net/ip.h> 65#include <net/ip.h>
65#include <net/protocol.h> 66#include <net/protocol.h>
@@ -81,6 +82,7 @@
81#include <linux/mutex.h> 82#include <linux/mutex.h>
82#include <linux/if_vlan.h> 83#include <linux/if_vlan.h>
83#include <linux/virtio_net.h> 84#include <linux/virtio_net.h>
85#include <linux/errqueue.h>
84 86
85#ifdef CONFIG_INET 87#ifdef CONFIG_INET
86#include <net/inet_common.h> 88#include <net/inet_common.h>
@@ -314,6 +316,8 @@ static inline struct packet_sock *pkt_sk(struct sock *sk)
314 316
315static void packet_sock_destruct(struct sock *sk) 317static void packet_sock_destruct(struct sock *sk)
316{ 318{
319 skb_queue_purge(&sk->sk_error_queue);
320
317 WARN_ON(atomic_read(&sk->sk_rmem_alloc)); 321 WARN_ON(atomic_read(&sk->sk_rmem_alloc));
318 WARN_ON(atomic_read(&sk->sk_wmem_alloc)); 322 WARN_ON(atomic_read(&sk->sk_wmem_alloc));
319 323
@@ -482,6 +486,9 @@ retry:
482 skb->dev = dev; 486 skb->dev = dev;
483 skb->priority = sk->sk_priority; 487 skb->priority = sk->sk_priority;
484 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;
485 492
486 dev_queue_xmit(skb); 493 dev_queue_xmit(skb);
487 rcu_read_unlock(); 494 rcu_read_unlock();
@@ -1187,6 +1194,9 @@ static int packet_snd(struct socket *sock,
1187 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);
1188 if (err) 1195 if (err)
1189 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;
1190 1200
1191 skb->protocol = proto; 1201 skb->protocol = proto;
1192 skb->dev = dev; 1202 skb->dev = dev;
@@ -1486,6 +1496,51 @@ out:
1486 return err; 1496 return err;
1487} 1497}
1488 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
1489/* 1544/*
1490 * 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.
1491 * If necessary we block. 1546 * If necessary we block.
@@ -1501,7 +1556,7 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
1501 int vnet_hdr_len = 0; 1556 int vnet_hdr_len = 0;
1502 1557
1503 err = -EINVAL; 1558 err = -EINVAL;
1504 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))
1505 goto out; 1560 goto out;
1506 1561
1507#if 0 1562#if 0
@@ -1510,6 +1565,11 @@ static int packet_recvmsg(struct kiocb *iocb, struct socket *sock,
1510 return -ENODEV; 1565 return -ENODEV;
1511#endif 1566#endif
1512 1567
1568 if (flags & MSG_ERRQUEUE) {
1569 err = packet_recv_error(sk, msg, len);
1570 goto out;
1571 }
1572
1513 /* 1573 /*
1514 * Call the generic datagram receiver. This handles all sorts 1574 * Call the generic datagram receiver. This handles all sorts
1515 * 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
@@ -1691,9 +1751,9 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
1691 if (i->alen != dev->addr_len) 1751 if (i->alen != dev->addr_len)
1692 return -EINVAL; 1752 return -EINVAL;
1693 if (what > 0) 1753 if (what > 0)
1694 return dev_mc_add(dev, i->addr, i->alen, 0); 1754 return dev_mc_add(dev, i->addr);
1695 else 1755 else
1696 return dev_mc_delete(dev, i->addr, i->alen, 0); 1756 return dev_mc_del(dev, i->addr);
1697 break; 1757 break;
1698 case PACKET_MR_PROMISC: 1758 case PACKET_MR_PROMISC:
1699 return dev_set_promiscuity(dev, what); 1759 return dev_set_promiscuity(dev, what);
@@ -1705,9 +1765,9 @@ static int packet_dev_mc(struct net_device *dev, struct packet_mclist *i,
1705 if (i->alen != dev->addr_len) 1765 if (i->alen != dev->addr_len)
1706 return -EINVAL; 1766 return -EINVAL;
1707 if (what > 0) 1767 if (what > 0)
1708 return dev_unicast_add(dev, i->addr); 1768 return dev_uc_add(dev, i->addr);
1709 else 1769 else
1710 return dev_unicast_delete(dev, i->addr); 1770 return dev_uc_del(dev, i->addr);
1711 break; 1771 break;
1712 default: 1772 default:
1713 break; 1773 break;