From 4e55f5785825f18b1eb6c5cc5a9717e276925805 Mon Sep 17 00:00:00 2001 From: "Jorge Boncompte [DTI2]" Date: Mon, 21 Nov 2011 10:25:57 +0000 Subject: atm: Introduce vcc_process_recv_queue This function moves the implementation found in the clip and br2684 modules to common code, correctly unlinks the skb from the queue before pushing it and makes pppoatm use it. Signed-off-by: Jorge Boncompte [DTI2] Signed-off-by: David S. Miller --- net/atm/common.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'net/atm/common.c') diff --git a/net/atm/common.c b/net/atm/common.c index 14ff9fe39989..0b4c58fe3919 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -214,6 +214,26 @@ void vcc_release_async(struct atm_vcc *vcc, int reply) } EXPORT_SYMBOL(vcc_release_async); +void vcc_process_recv_queue(struct atm_vcc *vcc) +{ + struct sk_buff_head queue, *rq; + struct sk_buff *skb, *tmp; + unsigned long flags; + + __skb_queue_head_init(&queue); + rq = &sk_atm(vcc)->sk_receive_queue; + + spin_lock_irqsave(&rq->lock, flags); + skb_queue_splice_init(rq, &queue); + spin_unlock_irqrestore(&rq->lock, flags); + + skb_queue_walk_safe(&queue, skb, tmp) { + __skb_unlink(skb, &queue); + vcc->push(vcc, skb); + } +} +EXPORT_SYMBOL(vcc_process_recv_queue); + void atm_dev_signal_change(struct atm_dev *dev, char signal) { pr_debug("%s signal=%d dev=%p number=%d dev->signal=%d\n", -- cgit From 40ba84993d66469d336099c5af74c3da5b73e28d Mon Sep 17 00:00:00 2001 From: "Jorge Boncompte [DTI2]" Date: Mon, 21 Nov 2011 10:25:58 +0000 Subject: atm: Allow MSG_PEEK for atm sockets Now that the vcc backends do the right thing with respect the receive queue on registration, allow MSK_PEEK for atm sockets. This allows a userspace program to inspect the packets and decide what backend to use to handle them. Signed-off-by: Jorge Boncompte [DTI2] Signed-off-by: David S. Miller --- net/atm/common.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'net/atm/common.c') diff --git a/net/atm/common.c b/net/atm/common.c index 0b4c58fe3919..b4b44dbed645 100644 --- a/net/atm/common.c +++ b/net/atm/common.c @@ -522,8 +522,11 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, if (sock->state != SS_CONNECTED) return -ENOTCONN; - if (flags & ~MSG_DONTWAIT) /* only handle MSG_DONTWAIT */ + + /* only handle MSG_DONTWAIT and MSG_PEEK */ + if (flags & ~(MSG_DONTWAIT | MSG_PEEK)) return -EOPNOTSUPP; + vcc = ATM_SD(sock); if (test_bit(ATM_VF_RELEASED, &vcc->flags) || test_bit(ATM_VF_CLOSE, &vcc->flags) || @@ -544,8 +547,13 @@ int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, if (error) return error; sock_recv_ts_and_drops(msg, sk, skb); - pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc), skb->truesize); - atm_return(vcc, skb->truesize); + + if (!(flags & MSG_PEEK)) { + pr_debug("%d -= %d\n", atomic_read(&sk->sk_rmem_alloc), + skb->truesize); + atm_return(vcc, skb->truesize); + } + skb_free_datagram(sk, skb); return copied; } -- cgit