All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@redhat.com>
To: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
Cc: netdev@vger.kernel.org
Subject: Re: [PATCH 5/6] Phonet: implement GPRS virtual interface over PEP socket
Date: Wed, 1 Oct 2008 10:32:33 -0300	[thread overview]
Message-ID: <20081001133233.GG970@ghostprotocols.net> (raw)
In-Reply-To: <1222855985-22859-5-git-send-email-remi.denis-courmont@nokia.com>

Em Wed, Oct 01, 2008 at 01:13:04PM +0300, Remi Denis-Courmont escreveu:
> From: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
> 
> Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
> ---
>  include/linux/phonet.h    |    8 +
>  include/linux/socket.h    |    1 +
>  include/net/phonet/gprs.h |   38 +++++
>  include/net/phonet/pep.h  |    1 +
>  net/phonet/Makefile       |    2 +-
>  net/phonet/pep-gprs.c     |  341 +++++++++++++++++++++++++++++++++++++++++++++
>  net/phonet/pep.c          |  157 ++++++++++++++++++++--
>  net/phonet/socket.c       |    8 +-
>  8 files changed, 542 insertions(+), 14 deletions(-)
>  create mode 100644 include/net/phonet/gprs.h
>  create mode 100644 net/phonet/pep-gprs.c
> 
> diff --git a/include/linux/phonet.h b/include/linux/phonet.h
> index f921852..c9609f9 100644
> --- a/include/linux/phonet.h
> +++ b/include/linux/phonet.h
> @@ -31,9 +31,17 @@
>  #define PN_PROTO_PIPE		2
>  #define PHONET_NPROTO		3
>  
> +/* Socket options for SOL_PNPIPE level */
> +#define PNPIPE_ENCAP		1
> +#define PNPIPE_IFINDEX		2
> +
>  #define PNADDR_ANY		0
>  #define PNPORT_RESOURCE_ROUTING	0
>  
> +/* Values for PNPIPE_ENCAP option */
> +#define PNPIPE_ENCAP_NONE	0
> +#define PNPIPE_ENCAP_IP		1
> +
>  /* ioctls */
>  #define SIOCPNGETOBJECT		(SIOCPROTOPRIVATE + 0)
>  
> diff --git a/include/linux/socket.h b/include/linux/socket.h
> index 818ca33..20fc4bb 100644
> --- a/include/linux/socket.h
> +++ b/include/linux/socket.h
> @@ -297,6 +297,7 @@ struct ucred {
>  #define SOL_RXRPC	272
>  #define SOL_PPPOL2TP	273
>  #define SOL_BLUETOOTH	274
> +#define SOL_PNPIPE	275
>  
>  /* IPX options */
>  #define IPX_TYPE	1
> diff --git a/include/net/phonet/gprs.h b/include/net/phonet/gprs.h
> new file mode 100644
> index 0000000..928daf5
> --- /dev/null
> +++ b/include/net/phonet/gprs.h
> @@ -0,0 +1,38 @@
> +/*
> + * File: pep_gprs.h
> + *
> + * GPRS over Phonet pipe end point socket
> + *
> + * Copyright (C) 2008 Nokia Corporation.
> + *
> + * Author: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> + * 02110-1301 USA
> + */
> +
> +#ifndef NET_PHONET_GPRS_H
> +#define NET_PHONET_GPRS_H
> +
> +struct sock;
> +struct sk_buff;
> +
> +int pep_writeable(struct sock *sk);
> +int pep_write(struct sock *sk, struct sk_buff *skb);
> +struct sk_buff *pep_read(struct sock *sk);
> +
> +int gprs_attach(struct sock *sk);
> +void gprs_detach(struct sock *sk);
> +
> +#endif
> diff --git a/include/net/phonet/pep.h b/include/net/phonet/pep.h
> index b06852b..a202adc 100644
> --- a/include/net/phonet/pep.h
> +++ b/include/net/phonet/pep.h
> @@ -35,6 +35,7 @@ struct pep_sock {
>  	struct sock		*listener;
>  	struct sk_buff_head	ctrlreq_queue;
>  #define PNPIPE_CTRLREQ_MAX	10
> +	int			ifindex;
>  	u16			peer_type;	/* peer type/subtype */
>  	u8			pipe_handle;
>  
> diff --git a/net/phonet/Makefile b/net/phonet/Makefile
> index 505df2a..d62bbba 100644
> --- a/net/phonet/Makefile
> +++ b/net/phonet/Makefile
> @@ -8,4 +8,4 @@ phonet-objs := \
>  	sysctl.o \
>  	af_phonet.o
>  
> -pn_pep-objs := pep.o
> +pn_pep-objs := pep.o pep-gprs.o
> diff --git a/net/phonet/pep-gprs.c b/net/phonet/pep-gprs.c
> new file mode 100644
> index 0000000..3341346
> --- /dev/null
> +++ b/net/phonet/pep-gprs.c
> @@ -0,0 +1,341 @@
> +/*
> + * File: pep-gprs.c
> + *
> + * GPRS over Phonet pipe end point socket
> + *
> + * Copyright (C) 2008 Nokia Corporation.
> + *
> + * Author: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * version 2 as published by the Free Software Foundation.
> + *
> + * This program is distributed in the hope that it will be useful, but
> + * WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
> + * 02110-1301 USA
> + */
> +
> +#include <linux/kernel.h>
> +#include <linux/netdevice.h>
> +#include <linux/if_ether.h>
> +#include <linux/if_arp.h>
> +#include <net/sock.h>
> +
> +#include <linux/if_phonet.h>
> +#include <net/tcp_states.h>
> +#include <net/phonet/gprs.h>
> +
> +#define GPRS_DEFAULT_MTU 1400
> +
> +struct gprs_dev {
> +	struct sock		*sk;
> +	void			(*old_state_change)(struct sock *);
> +	void			(*old_data_ready)(struct sock *, int);
> +	void			(*old_write_space)(struct sock *);
> +
> +	struct net_device	*net;
> +	struct net_device_stats	stats;
> +
> +	struct sk_buff_head	tx_queue;
> +	struct work_struct	tx_work;
> +	spinlock_t		tx_lock;
> +	unsigned		tx_max;
> +};
> +
> +/*
> + * Socket callbacks
> + */
> +
> +static void gprs_state_change(struct sock *sk)
> +{
> +	struct gprs_dev *dev = sk->sk_user_data;
> +
> +	if (sk->sk_state == TCP_CLOSE_WAIT) {
> +		netif_stop_queue(dev->net);
> +		netif_carrier_off(dev->net);
> +	}
> +}
> +
> +static int gprs_recv(struct gprs_dev *dev, struct sk_buff *skb)
> +{
> +	int err = 0;
> +	u16 protocol;
> +
> +	if (!pskb_may_pull(skb, 1))
> +		goto drop;
> +
> +	/* Look at IP version field */
> +	switch (skb->data[0] >> 4) {
> +	case 4:
> +		protocol = htons(ETH_P_IP);
> +		break;
> +	case 6:
> +		protocol = htons(ETH_P_IPV6);
> +		break;
> +	default:
> +		err = -EINVAL;
> +		goto drop;
> +	}
> +
> +	if (likely(skb_headroom(skb) & 3)) {
> +		struct sk_buff *rskb, *fs;
> +		int flen = 0;
> +
> +		/* Phonet Pipe data header is misaligned (3 bytes),
> +		 * so wrap the IP packet as a single fragment of an head-less
> +		 * socket buffer. The network stack will pull what it needs,
> +		 * but at least, the whole IP payload is not memcpy'd. */
> +		rskb = netdev_alloc_skb(dev->net, 0);
> +		if (!rskb) {
> +			err = -ENOBUFS;
> +			goto drop;
> +		}
> +		skb_shinfo(rskb)->frag_list = skb;
> +		rskb->len += skb->len;
> +		rskb->data_len += rskb->len;
> +		rskb->truesize += rskb->len;
> +
> +		/* Avoid nested fragments */
> +		for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next)
> +			flen += fs->len;
> +		skb->next = skb_shinfo(skb)->frag_list;
> +		skb_shinfo(skb)->frag_list = NULL;
> +		skb->len -= flen;
> +		skb->data_len -= flen;
> +		skb->truesize -= flen;
> +
> +		skb = rskb;
> +	}
> +
> +	skb->protocol = protocol;
> +	skb_reset_mac_header(skb);
> +	skb->dev = dev->net;

Perhaps introduce gprs_type_trans() and do:

	skb->protocol = gprs_type_trans() ?

Look at:

[acme@doppio linux-2.6]$ grep _type_trans tags | cut -f  1 | sort -u
ax25_type_trans
cisco_type_trans
dvb_net_eth_type_trans
ether1394_type_trans
eth_type_trans
farsync_type_trans
fddi_type_trans
hdlc_type_trans
hippi_type_trans
isdn_net_type_trans
lan_type_trans
mpt_lan_type_trans
myri_type_trans
plip_type_trans
ppp_type_trans
raw_type_trans
tr_type_trans
x25_type_trans
[acme@doppio linux-2.6]$

> +
> +	if (likely(dev->net->flags & IFF_UP)) {
> +		dev->stats.rx_packets++;
> +		dev->stats.rx_bytes += skb->len;
> +		netif_rx(skb);
> +		skb = NULL;
> +	} else
> +		err = -ENODEV;
> +
> +drop:
> +	if (skb) {
> +		dev_kfree_skb(skb);
> +		dev->stats.rx_dropped++;
> +	}
> +	return err;
> +}
> +
> +static void gprs_data_ready(struct sock *sk, int len)
> +{
> +	struct gprs_dev *dev = sk->sk_user_data;
> +	struct sk_buff *skb;
> +
> +	while ((skb = pep_read(sk)) != NULL) {
> +		skb_orphan(skb);
> +		gprs_recv(dev, skb);
> +	}
> +}
> +
> +static void gprs_write_space(struct sock *sk)
> +{
> +	struct gprs_dev *dev = sk->sk_user_data;
> +	unsigned credits = pep_writeable(sk);
> +
> +	spin_lock_bh(&dev->tx_lock);
> +	dev->tx_max = credits;
> +	if (credits > skb_queue_len(&dev->tx_queue))
> +		netif_wake_queue(dev->net);
> +	spin_unlock_bh(&dev->tx_lock);
> +}
> +
> +/*
> + * Network device callbacks
> + */
> +
> +static int gprs_xmit(struct sk_buff *skb, struct net_device *net)
> +{
> +	struct gprs_dev *dev = netdev_priv(net);
> +
> +	switch (skb->protocol) {
> +	case  htons(ETH_P_IP):
> +	case  htons(ETH_P_IPV6):
> +		break;
> +	default:
> +		dev_kfree_skb(skb);
> +		return 0;
> +	}
> +
> +	spin_lock(&dev->tx_lock);
> +	if (likely(skb_queue_len(&dev->tx_queue) < dev->tx_max)) {
> +		skb_queue_tail(&dev->tx_queue, skb);
> +		skb = NULL;
> +	}
> +	if (skb_queue_len(&dev->tx_queue) >= dev->tx_max)
> +		netif_stop_queue(net);
> +	spin_unlock(&dev->tx_lock);
> +
> +	schedule_work(&dev->tx_work);
> +	if (unlikely(skb))
> +		dev_kfree_skb(skb);
> +	return 0;
> +}
> +
> +static void gprs_tx(struct work_struct *work)
> +{
> +	struct gprs_dev *dev = container_of(work, struct gprs_dev, tx_work);
> +	struct sock *sk = dev->sk;
> +	struct sk_buff *skb;
> +
> +	while ((skb = skb_dequeue(&dev->tx_queue)) != NULL) {
> +		int err;
> +
> +		dev->stats.tx_bytes += skb->len;
> +		dev->stats.tx_packets++;
> +
> +		skb_orphan(skb);
> +		skb_set_owner_w(skb, sk);
> +
> +		lock_sock(sk);
> +		err = pep_write(sk, skb);
> +		if (err) {
> +			if (net_ratelimit())
> +				printk(KERN_WARNING"%s: TX error (%d)\n",
> +					dev->net->name, err);

LIMIT_NETDEBUG()

> +			dev->stats.tx_aborted_errors++;
> +			dev->stats.tx_errors++;
> +		}
> +		release_sock(sk);
> +	}
> +
> +	lock_sock(sk);
> +	gprs_write_space(sk);
> +	release_sock(sk);
> +}
> +
> +static int gprs_set_mtu(struct net_device *net, int new_mtu)
> +{
> +	if ((new_mtu < 576) || (new_mtu > (PHONET_MAX_MTU - 11)))
> +		return -EINVAL;
> +
> +	net->mtu = new_mtu;
> +	return 0;
> +}
> +
> +static struct net_device_stats *gprs_get_stats(struct net_device *net)
> +{
> +	struct gprs_dev *dev = netdev_priv(net);
> +
> +	return &dev->stats;
> +}
> +
> +static void gprs_setup(struct net_device *net)
> +{
> +	net->features		= NETIF_F_FRAGLIST;
> +	net->type		= ARPHRD_NONE;
> +	net->flags		= IFF_POINTOPOINT | IFF_NOARP;
> +	net->mtu		= GPRS_DEFAULT_MTU;
> +	net->hard_header_len	= 0;
> +	net->addr_len		= 0;
> +	net->tx_queue_len	= 10;
> +
> +	net->destructor		= free_netdev;
> +	net->hard_start_xmit	= gprs_xmit; /* mandatory */
> +	net->change_mtu		= gprs_set_mtu;
> +	net->get_stats		= gprs_get_stats;
> +}
> +
> +/*
> + * External interface
> + */
> +
> +/*
> + * Attach a GPRS interface to a datagram socket.
> + * Returns the interface index on success, negative error code on error.
> + */
> +int gprs_attach(struct sock *sk)
> +{
> +	static const char ifname[] = "gprs%d";
> +	struct gprs_dev *dev;
> +	struct net_device *net;
> +	int err;
> +
> +	if (unlikely(sk->sk_type == SOCK_STREAM))
> +		return -EINVAL; /* need packet boundaries */
> +
> +	/* Create net device */
> +	net = alloc_netdev(sizeof(*dev), ifname, gprs_setup);
> +	if (!net)
> +		return -ENOMEM;
> +	dev = netdev_priv(net);
> +	dev->net = net;
> +	dev->tx_max = 0;
> +	spin_lock_init(&dev->tx_lock);
> +	skb_queue_head_init(&dev->tx_queue);
> +	INIT_WORK(&dev->tx_work, gprs_tx);
> +
> +	netif_stop_queue(net);
> +	err = register_netdev(net);
> +	if (err) {
> +		free_netdev(net);
> +		return err;
> +	}
> +
> +	lock_sock(sk);
> +	if (unlikely(sk->sk_user_data)) {
> +		err = -EBUSY;
> +		goto out_rel;
> +	}
> +	if (unlikely((1 << sk->sk_state & (TCPF_CLOSE|TCPF_LISTEN)) ||
> +			sock_flag(sk, SOCK_DEAD))) {
> +		err = -EINVAL;
> +		goto out_rel;
> +	}
> +	sk->sk_user_data	= dev;
> +	dev->old_state_change	= sk->sk_state_change;
> +	dev->old_data_ready	= sk->sk_data_ready;
> +	dev->old_write_space	= sk->sk_write_space;
> +	sk->sk_state_change	= gprs_state_change;
> +	sk->sk_data_ready	= gprs_data_ready;
> +	sk->sk_write_space	= gprs_write_space;
> +	release_sock(sk);
> +
> +	sock_hold(sk);
> +	dev->sk = sk;
> +
> +	printk(KERN_DEBUG"%s: attached\n", net->name);
> +	gprs_write_space(sk); /* kick off TX */
> +	return net->ifindex;
> +
> +out_rel:
> +	release_sock(sk);
> +	unregister_netdev(net);
> +	return err;
> +}
> +
> +void gprs_detach(struct sock *sk)
> +{
> +	struct gprs_dev *dev = sk->sk_user_data;
> +	struct net_device *net = dev->net;
> +
> +	lock_sock(sk);
> +	sk->sk_user_data	= NULL;
> +	sk->sk_state_change	= dev->old_state_change;
> +	sk->sk_data_ready	= dev->old_data_ready;
> +	sk->sk_write_space	= dev->old_write_space;
> +	release_sock(sk);
> +
> +	printk(KERN_DEBUG"%s: detached\n", net->name);
> +	unregister_netdev(net);
> +	flush_scheduled_work();
> +	sock_put(sk);
> +	skb_queue_purge(&dev->tx_queue);
> +}
> diff --git a/net/phonet/pep.c b/net/phonet/pep.c
> index 9a2ed45..f0c212f 100644
> --- a/net/phonet/pep.c
> +++ b/net/phonet/pep.c
> @@ -31,6 +31,7 @@
>  #include <linux/phonet.h>
>  #include <net/phonet/phonet.h>
>  #include <net/phonet/pep.h>
> +#include <net/phonet/gprs.h>
>  
>  /* sk_state values:
>   * TCP_CLOSE		sock not in use yet
> @@ -610,6 +611,7 @@ drop:
>  static void pep_sock_close(struct sock *sk, long timeout)
>  {
>  	struct pep_sock *pn = pep_sk(sk);
> +	int ifindex = 0;
>  
>  	sk_common_release(sk);
>  
> @@ -623,7 +625,12 @@ static void pep_sock_close(struct sock *sk, long timeout)
>  			sk_del_node_init(sknode);
>  		sk->sk_state = TCP_CLOSE;
>  	}
> +	ifindex = pn->ifindex;
> +	pn->ifindex = 0;
>  	release_sock(sk);
> +
> +	if (ifindex)
> +		gprs_detach(sk);
>  }
>  
>  static int pep_wait_connreq(struct sock *sk, int noblock)
> @@ -728,12 +735,105 @@ static int pep_init(struct sock *sk)
>  	return 0;
>  }
>  
> +static int pep_setsockopt(struct sock *sk, int level, int optname,
> +				char __user *optval, int optlen)
> +{
> +	struct pep_sock *pn = pep_sk(sk);
> +	int val = 0, err = 0;
> +
> +	if (level != SOL_PNPIPE)
> +		return -ENOPROTOOPT;
> +	if (optlen >= sizeof(int)) {
> +		if (get_user(val, (int __user *) optval))
> +			return -EFAULT;
> +	}
> +
> +	lock_sock(sk);
> +	switch (optname) {
> +	case PNPIPE_ENCAP:
> +		if (val && val != PNPIPE_ENCAP_IP) {
> +			err = -EINVAL;
> +			break;
> +		}
> +		if (!pn->ifindex == !val)
> +			break; /* Nothing to do! */
> +		if (!capable(CAP_NET_ADMIN)) {
> +			err = -EPERM;
> +			break;
> +		}
> +		if (val) {
> +			release_sock(sk);
> +			err = gprs_attach(sk);
> +			if (err > 0) {
> +				pn->ifindex = err;
> +				err = 0;
> +			}
> +		} else {
> +			pn->ifindex = 0;
> +			release_sock(sk);
> +			gprs_detach(sk);
> +			err = 0;
> +		}
> +		goto out_norel;
> +	default:
> +		err = -ENOPROTOOPT;
> +	}
> +	release_sock(sk);
> +
> +out_norel:
> +	return err;
> +}
> +
> +static int pep_getsockopt(struct sock *sk, int level, int optname,
> +				char __user *optval, int __user *optlen)
> +{
> +	struct pep_sock *pn = pep_sk(sk);
> +	int len, val;
> +
> +	if (level != SOL_PNPIPE)
> +		return -ENOPROTOOPT;
> +	if (get_user(len, optlen))
> +		return -EFAULT;
> +
> +	switch (optname) {
> +	case PNPIPE_ENCAP:
> +		val = pn->ifindex ? PNPIPE_ENCAP_IP : PNPIPE_ENCAP_NONE;
> +		break;
> +	case PNPIPE_IFINDEX:
> +		val = pn->ifindex;
> +		break;
> +	default:
> +		return -ENOPROTOOPT;
> +	}
> +
> +	len = min_t(unsigned int, sizeof(int), len);
> +	if (put_user(len, optlen))
> +		return -EFAULT;
> +	if (put_user(val, (int __user *) optval))
> +		return -EFAULT;
> +	return 0;
> +}
> +
> +static int pipe_skb_send(struct sock *sk, struct sk_buff *skb)
> +{
> +	struct pep_sock *pn = pep_sk(sk);
> +	struct pnpipehdr *ph;
> +
> +	ph = (struct pnpipehdr *)skb_push(skb, 3);

skb_reset_transport_header + pnp_hdr()?

> +	ph->utid = 0;
> +	ph->message_id = PNS_PIPE_DATA;
> +	ph->pipe_handle = pn->pipe_handle;
> +	if (pn_flow_safe(pn->tx_fc) && pn->tx_credits)
> +		pn->tx_credits--;
> +
> +	return pn_skb_send(sk, skb, &pipe_srv);
> +}
> +
>  static int pep_sendmsg(struct kiocb *iocb, struct sock *sk,
>  			struct msghdr *msg, size_t len)
>  {
>  	struct pep_sock *pn = pep_sk(sk);
>  	struct sk_buff *skb = NULL;
> -	struct pnpipehdr *ph;
>  	long timeo;
>  	int flags = msg->msg_flags;
>  	int err, done;
> @@ -799,14 +899,7 @@ disabled:
>  	if (err < 0)
>  		goto out;
>  
> -	ph = (struct pnpipehdr *)skb_push(skb, 3);
> -	ph->utid = 0;
> -	ph->message_id = PNS_PIPE_DATA;
> -	ph->pipe_handle = pn->pipe_handle;
> -	if (pn_flow_safe(pn->tx_fc)) /* credit-based flow control */
> -		pn->tx_credits--;
> -
> -	err = pn_skb_send(sk, skb, &pipe_srv);
> +	err = pipe_skb_send(sk, skb);
>  	if (err >= 0)
>  		err = len; /* success! */
>  	skb = NULL;
> @@ -817,6 +910,50 @@ out:
>  	return err;
>  }
>  
> +int pep_writeable(struct sock *sk)
> +{
> +	struct pep_sock *pn = pep_sk(sk);
> +
> +	return (sk->sk_state == TCP_ESTABLISHED) ? pn->tx_credits : 0;
> +}
> +
> +int pep_write(struct sock *sk, struct sk_buff *skb)
> +{
> +	struct sk_buff *rskb, *fs;
> +	int flen = 0;
> +
> +	rskb = alloc_skb(MAX_PNPIPE_HEADER, GFP_ATOMIC);
> +	if (!rskb) {
> +		kfree_skb(skb);
> +		return -ENOMEM;
> +	}
> +	skb_shinfo(rskb)->frag_list = skb;
> +	rskb->len += skb->len;
> +	rskb->data_len += rskb->len;
> +	rskb->truesize += rskb->len;
> +
> +	/* Avoid nested fragments */
> +	for (fs = skb_shinfo(skb)->frag_list; fs; fs = fs->next)
> +		flen += fs->len;
> +	skb->next = skb_shinfo(skb)->frag_list;
> +	skb_shinfo(skb)->frag_list = NULL;
> +	skb->len -= flen;
> +	skb->data_len -= flen;
> +	skb->truesize -= flen;
> +
> +	skb_reserve(rskb, MAX_PHONET_HEADER + 3);
> +	return pipe_skb_send(sk, rskb);
> +}
> +
> +struct sk_buff *pep_read(struct sock *sk)
> +{
> +	struct sk_buff *skb = skb_dequeue(&sk->sk_receive_queue);
> +
> +	if (sk->sk_state == TCP_ESTABLISHED)
> +		pipe_grant_credits(sk);
> +	return skb;
> +}
> +
>  static int pep_recvmsg(struct kiocb *iocb, struct sock *sk,
>  			struct msghdr *msg, size_t len, int noblock,
>  			int flags, int *addr_len)
> @@ -899,6 +1036,8 @@ static struct proto pep_proto = {
>  	.accept		= pep_sock_accept,
>  	.ioctl		= pep_ioctl,
>  	.init		= pep_init,
> +	.setsockopt	= pep_setsockopt,
> +	.getsockopt	= pep_getsockopt,
>  	.sendmsg	= pep_sendmsg,
>  	.recvmsg	= pep_recvmsg,
>  	.backlog_rcv	= pep_do_rcv,
> diff --git a/net/phonet/socket.c b/net/phonet/socket.c
> index a9c3d1f..d817401 100644
> --- a/net/phonet/socket.c
> +++ b/net/phonet/socket.c
> @@ -342,11 +342,11 @@ const struct proto_ops phonet_stream_ops = {
>  	.ioctl		= pn_socket_ioctl,
>  	.listen		= pn_socket_listen,
>  	.shutdown	= sock_no_shutdown,
> -	.setsockopt	= sock_no_setsockopt,
> -	.getsockopt	= sock_no_getsockopt,
> +	.setsockopt	= sock_common_setsockopt,
> +	.getsockopt	= sock_common_getsockopt,
>  #ifdef CONFIG_COMPAT
> -	.compat_setsockopt = sock_no_setsockopt,
> -	.compat_getsockopt = compat_sock_no_getsockopt,
> +	.compat_setsockopt = compat_sock_common_setsockopt,
> +	.compat_getsockopt = compat_sock_common_getsockopt,
>  #endif
>  	.sendmsg	= pn_socket_sendmsg,
>  	.recvmsg	= sock_common_recvmsg,
> -- 
> 1.5.4.3
> 
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2008-10-01 13:34 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-10-01 10:12 [PATCH 0/6] [RFC] Phonet pipes protocol (v2) Rémi Denis-Courmont
2008-10-01 10:13 ` [PATCH 1/6] Phonet: transport protocol auto-loading Remi Denis-Courmont
2008-10-01 12:45   ` Arnaldo Carvalho de Melo
2008-10-01 15:01     ` Marcel Holtmann
2008-10-03 13:49     ` Rémi Denis-Courmont
2008-10-01 10:13 ` [PATCH 2/6] Phonet: connected sockets glue Remi Denis-Courmont
2008-10-01 12:48   ` Arnaldo Carvalho de Melo
2008-10-01 10:13 ` [PATCH 3/6] Phonet: Pipe End Point for Phonet Pipes protocol Remi Denis-Courmont
2008-10-01 13:18   ` Arnaldo Carvalho de Melo
2008-10-02 10:50     ` Rémi Denis-Courmont
2008-10-02 13:41       ` Arnaldo Carvalho de Melo
2008-10-01 10:13 ` [PATCH 4/6] Phonet: receive pipe control requests as out-of-band data Remi Denis-Courmont
2008-10-01 10:13 ` [PATCH 5/6] Phonet: implement GPRS virtual interface over PEP socket Remi Denis-Courmont
2008-10-01 13:32   ` Arnaldo Carvalho de Melo [this message]
2008-10-01 10:13 ` [PATCH 6/6] Phonet: pipe end-point protocol documentation Remi Denis-Courmont
2008-10-01 15:19   ` Randy Macleod
2008-10-10 18:24   ` Randy Macleod
2008-10-11 19:30     ` David Miller
2008-10-14 15:06       ` Randy Macleod
2008-10-14 20:49         ` David Miller
2008-10-14 15:11       ` Randy Macleod
  -- strict thread matches above, loose matches on Subject: below --
2008-10-03 14:09 [PATCH 0/6] Phonet pipes protocol (take 3) Rémi Denis-Courmont
2008-10-03 14:09 ` [PATCH 5/6] Phonet: implement GPRS virtual interface over PEP socket Remi Denis-Courmont

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081001133233.GG970@ghostprotocols.net \
    --to=acme@redhat.com \
    --cc=netdev@vger.kernel.org \
    --cc=remi.denis-courmont@nokia.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.