[PATCH 09/14] Phonet: allocate and initialize new sockets

Previous thread: [PATCH] hso reset_resume patch by Denis Joseph Barrow on Tuesday, September 16, 2008 - 7:52 am. (1 message)

Next thread: [PATCH] ipvs: change some __constant_htons() to htons() by Brian Haley on Tuesday, September 16, 2008 - 8:11 am. (3 messages)
From: Rémi
Date: Tuesday, September 16, 2008 - 7:57 am

Hello,

This patch series introduces support for PhoNet,
the "Phone Network protocol". This protocol is the primary interface
to Nokia cellular modem engines. We are integrating it to the Linux
kernel in order to support HSPA cellular data connectivity on the
Maemo Software platform.

This patchset provides a simple datagram socket 
independent of the underlying hardware (network interface) through
which the modem is attached. We are in the process of contributing
a lower-layer driver through Linux OMAP.

This series is based on net-next-2.6, plus the tiny MISDN lockdep fix
I posted to netdev yesterday.

Any comments welcome.

--
 Documentation/networking/phonet.txt |  111 ++++++++
 include/linux/if_ether.h            |    1
 include/linux/if_phonet.h           |   16 +
 include/linux/phonet.h              |  136 ++++++++++
 include/linux/rtnetlink.h           |    4
 include/linux/socket.h              |    4
 include/net/phonet/phonet.h         |  103 +++++++
 include/net/phonet/pn_dev.h         |   63 ++++
 net/Kconfig                         |    1
 net/Makefile                        |    1
 net/core/sock.c                     |    9
 net/phonet/Kconfig                  |   11
 net/phonet/Makefile                 |   11
 net/phonet/af_phonet.c              |  485 +++++++++++++++++++++++++++++++++++-
 net/phonet/datagram.c               |  197 ++++++++++++++
 net/phonet/pn_dev.c                 |  232 +++++++++++++++++
 net/phonet/pn_netlink.c             |  239 +++++++++++++++++
 net/phonet/socket.c                 |  314 +++++++++++++++++++++++
 net/phonet/sysctl.c                 |  111 ++++++++
 19 files changed, 2036 insertions(+), 13 deletions(-)

Regards,

-- 
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 net/Kconfig  |    1 +
 net/Makefile |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

diff --git a/net/Kconfig b/net/Kconfig
index d87de48..9103a16 100644
--- a/net/Kconfig
+++ b/net/Kconfig
@@ -232,6 +232,7 @@ source "net/can/Kconfig"
 source "net/irda/Kconfig"
 source "net/bluetooth/Kconfig"
 source "net/rxrpc/Kconfig"
+source "net/phonet/Kconfig"
 
 config FIB_RULES
 	bool
diff --git a/net/Makefile b/net/Makefile
index 4f43e7f..acaf819 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -42,6 +42,7 @@ obj-$(CONFIG_AF_RXRPC)		+= rxrpc/
 obj-$(CONFIG_ATM)		+= atm/
 obj-$(CONFIG_DECNET)		+= decnet/
 obj-$(CONFIG_ECONET)		+= econet/
+obj-$(CONFIG_PHONET)		+= phonet/
 ifneq ($(CONFIG_VLAN_8021Q),)
 obj-y				+= 8021q/
 endif
-- 
1.5.4.3

--

From: Arnaldo Carvalho de Melo
Date: Tuesday, September 16, 2008 - 9:06 am

Can't this be combined with 2/14?
--

From: Simon Horman
Date: Tuesday, September 16, 2008 - 9:52 pm

Also, I think that the patches need to be re-ordered somehow.
As things stand, applying patches (1,) 2 & 3 and setting
CONFIG_PHONET=y will try and build net/phonet/phonet.o,
but there is no source for that object at that point.

-- 
Simon Horman
  VA Linux Systems Japan K.K., Sydney, Australia Satellite Office
  H: www.vergenet.net/~horms/             W: www.valinux.co.jp/en

--

From: Rémi
Date: Wednesday, September 17, 2008 - 1:44 am

Woops. I'll switch to 1, 4, 2+3, 5...

-- 
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

This provides support for adding Phonet addresses to and removing
Phonet addresses from network devices.

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/pn_dev.h |   63 ++++++++++++
 net/phonet/Makefile         |    1 +
 net/phonet/af_phonet.c      |   12 ++
 net/phonet/pn_dev.c         |  233 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 309 insertions(+), 0 deletions(-)
 create mode 100644 include/net/phonet/pn_dev.h
 create mode 100644 net/phonet/pn_dev.c

diff --git a/include/net/phonet/pn_dev.h b/include/net/phonet/pn_dev.h
new file mode 100644
index 0000000..c53d364
--- /dev/null
+++ b/include/net/phonet/pn_dev.h
@@ -0,0 +1,63 @@
+/*
+ * File: pn_dev.h
+ *
+ * Phonet network device
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * 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 PN_DEV_H
+#define PN_DEV_H
+
+struct phonet_device_list {
+	struct list_head list;
+	spinlock_t lock;
+};
+
+extern struct phonet_device_list pndevs;
+
+struct phonet_device {
+	struct list_head list;
+	struct net_device *netdev;
+	struct list_head own;
+};
+
+struct phonet_address {
+	struct list_head list;
+	struct phonet_device *pnd;
+	uint8_t addr;
+	unsigned char prefix;
+};
+
+int phonet_device_init(void);
+void phonet_device_exit(void);
+struct phonet_device ...
From: Arnaldo Carvalho de Melo
Date: Tuesday, September 16, 2008 - 9:41 am

Please look at net/ipv4/tcp_minisocks.c to see how tcp_death_row is
initialized, that way you don't have to first initialize it to zeros
(BSS as it is static and uninitialized) and then, at phonet_device_init

Perhaps a phone_for_each_dev() macro like for_each_netdev() in


minor nitpick:

	if (pna != NULL)
		INIT_LIST_HEAD(&pna->list);


Not symetric, i.e. you have a list_add operation and not a list_del,
only one that in addition to removing from the list also destroys the

Why not use list_for_each_entry()? _safe() even, since



	if (what == NETDEV_UNREGISTER && pnd != NULL)
		phonet_device_free(pnd);

--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/phonet.h |    1 +
 net/phonet/af_phonet.c      |   20 ++++++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
index 8e7e42d..1131833 100644
--- a/include/net/phonet/phonet.h
+++ b/include/net/phonet/phonet.h
@@ -81,6 +81,7 @@ void pn_skb_get_dst_sockaddr(struct sk_buff *skb, struct sockaddr_pn *sa)
 
 /* Protocols in Phonet protocol family. */
 struct phonet_protocol {
+	const struct proto_ops	*ops;
 	struct proto		*prot;
 	int			sock_type;
 };
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index 317f30c..1628e7c 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -41,6 +41,8 @@ static inline void phonet_proto_put(struct phonet_protocol *pp);
 
 static int pn_socket_create(struct net *net, struct socket *sock, int protocol)
 {
+	struct sock *sk;
+	struct pn_sock *pn;
 	struct phonet_protocol *pnp;
 	int err;
 
@@ -71,8 +73,22 @@ static int pn_socket_create(struct net *net, struct socket *sock, int protocol)
 		goto out;
 	}
 
-	/* TODO: create and init the struct sock */
-	err = -EPROTONOSUPPORT;
+	sk = sk_alloc(net, PF_PHONET, GFP_KERNEL, pnp->prot);
+	if (sk == NULL) {
+		err = -ENOMEM;
+		goto out;
+	}
+
+	sock_init_data(sock, sk);
+	sock->state = SS_UNCONNECTED;
+	sock->ops = pnp->ops;
+	sk->sk_backlog_rcv = sk->sk_prot->backlog_rcv;
+	sk->sk_protocol = protocol;
+	pn = pn_sk(sk);
+	pn->sobject = 0;
+	pn->resource = 0;
+	sk->sk_prot->init(sk);
+	err = 0;
 
 out:
 	phonet_proto_put(pnp);
-- 
1.5.4.3

--

From: Arnaldo Carvalho de Melo
Date: Tuesday, September 16, 2008 - 9:53 am

From: Pavel Emelyanov
Date: Tuesday, September 16, 2008 - 11:42 am

This turns to be a little bit messy wrt net namespaces.
Look - you allow for sockets to be created (and isolated from each
other) in each namespace, the list of devices is global, whilst
the sysctls are visible in init_net only...

I'd propose to either make this protocol namespaces aware from the
very beginning or to explicitly prohibit any operations with it in
the non-init netns not to forget to fix it in the future (just like
it was done for all the protocols and is still true for most of them).

Thanks,
Pavel
--

From: Rémi
Date: Wednesday, September 17, 2008 - 1:30 am

Hello,


I expect pn_socket_create() should forbid this, no?

    if (net != &init_net)
            return -EAFNOSUPPORT;
    /* ... */

Hmmm, good point. Should I forbid adding an address to devices outside the 
initial namespace? what about a device with an existing address being 

Regards,

-- 
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
--

From: Pavel Emelyanov
Date: Friday, September 19, 2008 - 3:14 am

Well, to be honest, I'd prefer making this ns aware from the very
beginning, but not to force you make things you (probably) don't want

--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

This delivers received packet to the right socket, if any.

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/phonet.h |    1 +
 net/phonet/af_phonet.c      |   13 ++++++++++++-
 2 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
index e0fa080..8e7e42d 100644
--- a/include/net/phonet/phonet.h
+++ b/include/net/phonet/phonet.h
@@ -35,6 +35,7 @@
  */
 struct pn_sock {
 	struct sock	sk;
+	int		(*handler)(struct sock *, struct sk_buff *);
 	u16		sobject;
 	u8		resource;
 };
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index 12c72e1..317f30c 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -96,7 +96,9 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
 			struct net_device *orig_dev)
 {
 	struct phonethdr *ph;
+	struct sock *sk;
 	struct sockaddr_pn sa;
+	int err;
 	u16 len;
 
 	if (dev_net(dev) != &init_net)
@@ -120,7 +122,15 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
 	if (pn_sockaddr_get_addr(&sa) == 0)
 		goto out; /* currently, we cannot be device 0 */
 
-	/* TODO: put packets to sockets backlog */
+	sk = pn_find_sock_by_sa(&sa);
+	if (sk == NULL)
+		goto out;
+
+	/* Push data to the socket (or other sockets connected to it). */
+	err = pn_sk(sk)->handler(sk, skb);
+	sock_put(sk);
+
+	return err ? NET_RX_DROP : NET_RX_SUCCESS;
 
 out:
 	kfree_skb(skb);
@@ -196,6 +206,7 @@ static int __init phonet_init(void)
 {
 	int err;
 
+	phonet_socket_init();
 	err = sock_register(&phonet_proto_family);
 	if (err) {
 		printk(KERN_ALERT
-- 
1.5.4.3

--

From: Arnaldo Carvalho de Melo
Date: Tuesday, September 16, 2008 - 9:52 am

[Empty message]
From: Rémi
Date: Thursday, September 18, 2008 - 11:20 pm

Yes, thanks. I had missed sk_receive_skb(), in which case, sk_backlog_rcv() 
does not work so well.

-- 
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/linux/if_phonet.h |    2 ++
 net/phonet/af_phonet.c    |   29 +++++++++++++++++++++++++++++
 2 files changed, 31 insertions(+), 0 deletions(-)

diff --git a/include/linux/if_phonet.h b/include/linux/if_phonet.h
index 22df25f..94bc59b 100644
--- a/include/linux/if_phonet.h
+++ b/include/linux/if_phonet.h
@@ -12,3 +12,5 @@
 /* 6 bytes header + 65535 bytes payload */
 #define PHONET_MAX_MTU		65541
 #define PHONET_DEV_MTU		PHONET_MAX_MTU
+
+extern struct header_ops phonet_header_ops;
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index ec99413..2593d9c 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -101,6 +101,35 @@ static struct net_proto_family phonet_proto_family = {
 	.owner = THIS_MODULE,
 };
 
+/* Phonet device header operations */
+static int pn_header_create(struct sk_buff *skb, struct net_device *dev,
+				unsigned short type, const void *daddr,
+				const void *saddr, unsigned len)
+{
+	u8 *media = skb_push(skb, 1);
+
+	if (type != ETH_P_PHONET)
+		return -1;
+
+	if (!saddr)
+		saddr = dev->dev_addr;
+	*media = *(const u8 *)saddr;
+	return 1;
+}
+
+static int pn_header_parse(const struct sk_buff *skb, unsigned char *haddr)
+{
+	const u8 *media = skb_mac_header(skb);
+	*haddr = *media;
+	return 1;
+}
+
+struct header_ops phonet_header_ops = {
+	.create = pn_header_create,
+	.parse = pn_header_parse,
+};
+EXPORT_SYMBOL(phonet_header_ops);
+
 /*
  * Prepends an ISI header and sends a datagram.
  */
-- 
1.5.4.3

--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

This provides support for configuring Phonet addresses, notifying
Phonet configuration changes, and dumping the configuration.

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/phonet.h |    1 +
 net/phonet/Makefile         |    1 +
 net/phonet/af_phonet.c      |    1 +
 net/phonet/pn_netlink.c     |  240 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 243 insertions(+), 0 deletions(-)
 create mode 100644 net/phonet/pn_netlink.c

diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
index be02ee9..d62883c 100644
--- a/include/net/phonet/phonet.h
+++ b/include/net/phonet/phonet.h
@@ -68,4 +68,5 @@ struct phonet_protocol {
 int phonet_proto_register(int protocol, struct phonet_protocol *pp);
 void phonet_proto_unregister(int protocol, struct phonet_protocol *pp);
 
+void phonet_netlink_register(void);
 #endif
diff --git a/net/phonet/Makefile b/net/phonet/Makefile
index 980a386..4143c3e 100644
--- a/net/phonet/Makefile
+++ b/net/phonet/Makefile
@@ -2,4 +2,5 @@ obj-$(CONFIG_PHONET) += phonet.o
 
 phonet-objs := \
 	pn_dev.o \
+	pn_netlink.o \
 	af_phonet.o
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index 744b47f..12c72e1 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -210,6 +210,7 @@ static int __init phonet_init(void)
 	}
 
 	dev_add_pack(&phonet_packet_type);
+	phonet_netlink_register();
 	return 0;
 
 unregister:
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c
new file mode 100644
index 0000000..121b62e
--- /dev/null
+++ b/net/phonet/pn_netlink.c
@@ -0,0 +1,240 @@
+/*
+ * File: pn_netlink.c
+ *
+ * Phonet netlink interface
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Contact: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
+ * Original author: Sakari Ailus <sakari.ailus@nokia.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public ...
From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

When there is no listener socket for a received packet, send an error
back to the sender.

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 net/phonet/af_phonet.c |   82 +++++++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 78 insertions(+), 4 deletions(-)

diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index c18664d..3962969 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -134,7 +134,7 @@ EXPORT_SYMBOL(phonet_header_ops);
  * Prepends an ISI header and sends a datagram.
  */
 static int pn_send(struct sk_buff *skb, struct net_device *dev,
-			u16 dst, u16 src, u8 res)
+			u16 dst, u16 src, u8 res, u8 irq)
 {
 	struct phonethdr *ph;
 	int err;
@@ -163,7 +163,10 @@ static int pn_send(struct sk_buff *skb, struct net_device *dev,
 		skb_reset_mac_header(skb);
 		skb->pkt_type = PACKET_LOOPBACK;
 		skb_orphan(skb);
-		netif_rx_ni(skb);
+		if (irq)
+			netif_rx(skb);
+		else
+			netif_rx_ni(skb);
 		err = 0;
 	} else {
 		err = dev_hard_header(skb, dev, ntohs(skb->protocol),
@@ -181,6 +184,18 @@ drop:
 	return err;
 }
 
+static int pn_raw_send(const void *data, int len, struct net_device *dev,
+			u16 dst, u16 src, u8 res)
+{
+	struct sk_buff *skb = alloc_skb(MAX_PHONET_HEADER + len, GFP_ATOMIC);
+	if (skb == NULL)
+		return -ENOMEM;
+
+	skb_reserve(skb, MAX_PHONET_HEADER);
+	memcpy(skb_put(skb, len), data, len);
+	return pn_send(skb, dev, dst, src, res, 1);
+}
+
 /*
  * Create a Phonet header for the skb and send it out. Returns
  * non-zero error code if failed. The skb is freed then.
@@ -221,7 +236,7 @@ int pn_skb_send(struct sock *sk, struct sk_buff *skb,
 	spin_unlock_bh(&pndevs.lock);
 
 	err = pn_send(skb, dev, pn_sockaddr_get_object(target),
-			src, pn_sockaddr_get_resource(target));
+			src, pn_sockaddr_get_resource(target), 0);
 	dev_put(dev);
 	return err;
 
@@ -231,6 +246,60 @@ drop:
 }
 EXPORT_SYMBOL(pn_skb_send);
 
+static inline int can_respond(struct sk_buff ...
From: Arnaldo Carvalho de Melo
Date: Tuesday, September 16, 2008 - 10:11 am

Try not to access skb->data directly, probably you would be better off

--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

This provides the socket API for the Phonet protocols family.

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/linux/phonet.h      |    3 +
 include/net/phonet/phonet.h |   20 +++
 net/phonet/Makefile         |    1 +
 net/phonet/socket.c         |  312 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 336 insertions(+), 0 deletions(-)
 create mode 100644 net/phonet/socket.c

diff --git a/include/linux/phonet.h b/include/linux/phonet.h
index 000b6d7..4510458 100644
--- a/include/linux/phonet.h
+++ b/include/linux/phonet.h
@@ -32,6 +32,9 @@
 #define PNADDR_ANY		0
 #define PNPORT_RESOURCE_ROUTING	0
 
+/* ioctls */
+#define SIOCPNGETOBJECT		(SIOCPROTOPRIVATE + 0)
+
 /* Phonet protocol header */
 struct phonethdr {
 	uint8_t rdev;
diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
index d62883c..e0fa080 100644
--- a/include/net/phonet/phonet.h
+++ b/include/net/phonet/phonet.h
@@ -29,6 +29,25 @@
  */
 #define MAX_PHONET_HEADER	8
 
+/*
+ * Every Phonet* socket has this structure first in its
+ * protocol-specific structure under name c.
+ */
+struct pn_sock {
+	struct sock	sk;
+	u16		sobject;
+	u8		resource;
+};
+
+#define pn_sk(sk) ((struct pn_sock *)(sk))
+
+extern const struct proto_ops phonet_dgram_ops;
+
+struct sock *pn_find_sock_by_sa(const struct sockaddr_pn *sa);
+void pn_sock_hash(struct sock *sk);
+void pn_sock_unhash(struct sock *sk);
+int pn_sock_get_port(struct sock *sk, unsigned short sport);
+
 #define pn_hdr(skb) ((struct phonethdr *)skb_network_header(skb))
 
 /*
@@ -68,5 +87,6 @@ struct phonet_protocol {
 int phonet_proto_register(int protocol, struct phonet_protocol *pp);
 void phonet_proto_unregister(int protocol, struct phonet_protocol *pp);
 
+void phonet_socket_init(void);
 void phonet_netlink_register(void);
 #endif
diff --git a/net/phonet/Makefile b/net/phonet/Makefile
index 4143c3e..c1d671d 100644
--- a/net/phonet/Makefile
+++ b/net/phonet/Makefile
@@ -3,4 ...
From: Arnaldo Carvalho de Melo
Date: Tuesday, September 16, 2008 - 9:50 am

Why do this as a define and not like, say, tcp_sk(), that way you at
least guarantee that you will not end up using some non-sock pointer


See tcp_death_row on how to initialize it right here and not at some


I guess it is a requirement that each protocol will provide an ioctl
--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

This provides the basic SOCK_DGRAM transport protocol for Phonet.

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/phonet.h |    6 ++
 net/phonet/Makefile         |    1 +
 net/phonet/af_phonet.c      |  108 +++++++++++++++++++++++
 net/phonet/datagram.c       |  198 +++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 313 insertions(+), 0 deletions(-)
 create mode 100644 net/phonet/datagram.c

diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
index 1131833..ead764d 100644
--- a/include/net/phonet/phonet.h
+++ b/include/net/phonet/phonet.h
@@ -49,6 +49,9 @@ void pn_sock_hash(struct sock *sk);
 void pn_sock_unhash(struct sock *sk);
 int pn_sock_get_port(struct sock *sk, unsigned short sport);
 
+int pn_skb_send(struct sock *sk, struct sk_buff *skb,
+		const struct sockaddr_pn *target);
+
 #define pn_hdr(skb) ((struct phonethdr *)skb_network_header(skb))
 
 /*
@@ -91,4 +94,7 @@ void phonet_proto_unregister(int protocol, struct phonet_protocol *pp);
 
 void phonet_socket_init(void);
 void phonet_netlink_register(void);
+int isi_register(void);
+void isi_unregister(void);
+
 #endif
diff --git a/net/phonet/Makefile b/net/phonet/Makefile
index c1d671d..d218abc 100644
--- a/net/phonet/Makefile
+++ b/net/phonet/Makefile
@@ -4,4 +4,5 @@ phonet-objs := \
 	pn_dev.o \
 	pn_netlink.o \
 	socket.o \
+	datagram.o \
 	af_phonet.o
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index 1628e7c..ec99413 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -101,6 +101,107 @@ static struct net_proto_family phonet_proto_family = {
 	.owner = THIS_MODULE,
 };
 
+/*
+ * Prepends an ISI header and sends a datagram.
+ */
+static int pn_send(struct sk_buff *skb, struct net_device *dev,
+			u16 dst, u16 src, u8 res)
+{
+	struct phonethdr *ph;
+	int err;
+
+	if (skb->len > 0xfffd) {
+		err = -EMSGSIZE;
+		goto ...
From: Arnaldo Carvalho de Melo
Date: Tuesday, September 16, 2008 - 10:06 am

Here you could just use:

	ph = (struct phonethdr *)skb_network_header(skb);

	or even just:

	ph = pn_hdr(skb);


No need for __constant_htons(CONSTANT), htons will do the right thing



--

From: Rémi
Date: Thursday, September 18, 2008 - 11:33 pm

Taking into account that we push sizeof(*ph) in-between, this protects against 
protocol overflow a few lines down:
    ph->length = __cpu_to_be16(skb->len + 2 - sizeof(*ph));

I guess it deserves a /* comment */.

By the way, is the protocol stack or the device driver responsible for not 


Ok. There are quite many of these in net/ though... is that reserved for 
switch/case only?


The socket lock was not taken on the RX path, as I was not using 
sk_receive_skb(). I believe no state needs protection from softirq in the 
datagram protocol, other than the receive queue itself.

Of course, with sk_receive_skb(), I guess I could use lock_sock().

Thanks many times for the review,

-- 
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
--

From: Arnaldo Carvalho de Melo
Date: Friday, September 19, 2008 - 8:24 am

Nope, they should only be used when initializing static variables.

David, the following patch converts what is in net-next-2.6 net/ now:


commit 8e64a880d1f8a3df44648e0109f22a22322acc56
Author: Arnaldo Carvalho de Melo <acme@redhat.com>
Date:   Fri Sep 19 11:34:45 2008 -0300

    net: Use hton[sl]() instead of __constant_hton[sl]() where applicable
    
    Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 97688cd..8883e9c 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -48,7 +48,7 @@ static int vlan_dev_rebuild_header(struct sk_buff *skb)
 
 	switch (veth->h_vlan_encapsulated_proto) {
 #ifdef CONFIG_INET
-	case __constant_htons(ETH_P_IP):
+	case htons(ETH_P_IP):
 
 		/* TODO:  Confirm this will work with VLAN headers... */
 		return arp_find(veth->h_dest, skb);
diff --git a/net/atm/br2684.c b/net/atm/br2684.c
index 8d9a6f1..280de48 100644
--- a/net/atm/br2684.c
+++ b/net/atm/br2684.c
@@ -375,11 +375,11 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
 			if (memcmp
 			    (skb->data + 6, ethertype_ipv6,
 			     sizeof(ethertype_ipv6)) == 0)
-				skb->protocol = __constant_htons(ETH_P_IPV6);
+				skb->protocol = htons(ETH_P_IPV6);
 			else if (memcmp
 				 (skb->data + 6, ethertype_ipv4,
 				  sizeof(ethertype_ipv4)) == 0)
-				skb->protocol = __constant_htons(ETH_P_IP);
+				skb->protocol = htons(ETH_P_IP);
 			else
 				goto error;
 			skb_pull(skb, sizeof(llc_oui_ipv4));
@@ -404,9 +404,9 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
 			skb_reset_network_header(skb);
 			iph = ip_hdr(skb);
 			if (iph->version == 4)
-				skb->protocol = __constant_htons(ETH_P_IP);
+				skb->protocol = htons(ETH_P_IP);
 			else if (iph->version == 6)
-				skb->protocol = __constant_htons(ETH_P_IPV6);
+				skb->protocol = htons(ETH_P_IPV6);
 			else
 				goto error;
 			skb->pkt_type = PACKET_HOST;
diff --git a/net/core/dev.c ...
From: David Miller
Date: Saturday, September 20, 2008 - 10:21 pm

From: Arnaldo Carvalho de Melo <acme@redhat.com>

Applied, thanks Arnaldo.
--

From: Piet Delaney
Date: Friday, November 14, 2008 - 1:32 am

I see more downside with this patch with it's preventing the kernel
from being compiled -O0 when using kgdb or looking at KEXEC/KDUMP
core files with gdb.

--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

This is the basis for the Phonet protocol families, and introduces
the ETH_P_PHONET packet type and the PF_PHONET socket family.

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/phonet.h |   71 ++++++++++++++
 net/phonet/Makefile         |    3 +-
 net/phonet/af_phonet.c      |  218 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 291 insertions(+), 1 deletions(-)
 create mode 100644 include/net/phonet/phonet.h
 create mode 100644 net/phonet/af_phonet.c

diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
new file mode 100644
index 0000000..be02ee9
--- /dev/null
+++ b/include/net/phonet/phonet.h
@@ -0,0 +1,71 @@
+/*
+ * File: af_phonet.h
+ *
+ * Phonet sockets kernel definitions
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * 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 AF_PHONET_H
+#define AF_PHONET_H
+
+/*
+ * The lower layers may not require more space, ever. Make sure it's
+ * enough.
+ */
+#define MAX_PHONET_HEADER	8
+
+#define pn_hdr(skb) ((struct phonethdr *)skb_network_header(skb))
+
+/*
+ * Get the other party's sockaddr from received skb. The skb begins
+ * with a Phonet header.
+ */
+static inline
+void pn_skb_get_src_sockaddr(struct sk_buff *skb, struct sockaddr_pn *sa)
+{
+	struct phonethdr *ph = pn_hdr(skb);
+	uint16_t obj = ...
From: Arnaldo Carvalho de Melo
Date: Tuesday, September 16, 2008 - 9:17 am

Without looking in detail, first reaction is: don't we have sk_type in
struct sock? Can't it be used or what you would have in
ponet_protocol->sock_type be mapped to it?


Here, the mapping, and we even have struct socket sock->type in addition


I guess this will be done in the next patches, interesting way of

--

From: Rémi
Date: Wednesday, September 17, 2008 - 3:48 am

Hello,


I would need to have the socket type into struct proto, not in struct sock.
Other families have this "problem" as well (at least inet...).

However, I assume some transport protocols support more than one socket types, 
such that it is not possible to add a socket type to struct proto, right?

-- 
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

Signed-off-by: Rémi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 Documentation/networking/phonet.txt |  111 +++++++++++++++++++++++++++++++++++
 1 files changed, 111 insertions(+), 0 deletions(-)
 create mode 100644 Documentation/networking/phonet.txt

diff --git a/Documentation/networking/phonet.txt b/Documentation/networking/phonet.txt
new file mode 100644
index 0000000..f3c72e0
--- /dev/null
+++ b/Documentation/networking/phonet.txt
@@ -0,0 +1,111 @@
+Linux Phonet protocol family
+============================
+
+Introduction
+------------
+
+Phonet is a packet protocol used by Nokia cellular modems for both IPC
+and RPC. With the Linux Phonet socket family, Linux host processes can
+receive and send messages from/to the modem, or any other external
+device attached to the modem. The modem takes care of routing.
+
+Phonet packets can be exchanged through various hardware connections
+depending on the device, such as:
+  - USB with the CDC Phonet interface,
+  - infrared,
+  - Bluetooth,
+  - an RS232 serial port (with a dedicated "FBUS" line discipline),
+  - the SSI bus with some TI OMAP processors.
+
+
+Packets format
+--------------
+
+Phonet packet have a common header as follow:
+
+  struct phonethdr {
+    uint8_t  pn_media;  /* Media type (link-layer identifier) */
+    uint8_t  pn_rdev;   /* Receiver device ID */
+    uint8_t  pn_sdev;   /* Sender device ID */
+    uint8_t  pn_res;    /* Resource ID or function */
+    uint16_t pn_length; /* Big-endian message byte length (minus 6) */
+    uint8_t  pn_robj;   /* Receiver object ID */
+    uint8_t  pn_sobj;   /* Sender object ID */
+  };
+
+The device ID is split: the 6 higher order bits consitutes the device
+address, while the 2 lower order bits are used for multiplexing, as are
+the 8-bits object identifiers. As such, Phonet can be considered as a
+network layer with 6 bits of address space and 10 bits for transport
+protocol (much like port numbers in IP world).
+
+The modem always has ...
From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

Phonet endpoints are bound to individual ports.
This provides a /proc/sys/net/phonet (or sysctl) interface for
selecting the range of automatically allocated ports (much like the
ip_local_port_range with IPv4).

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/net/phonet/phonet.h |    3 +
 net/phonet/Makefile         |    1 +
 net/phonet/af_phonet.c      |    3 +
 net/phonet/socket.c         |    3 +-
 net/phonet/sysctl.c         |  113 +++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 122 insertions(+), 1 deletions(-)
 create mode 100644 net/phonet/sysctl.c

diff --git a/include/net/phonet/phonet.h b/include/net/phonet/phonet.h
index ead764d..8555bc7 100644
--- a/include/net/phonet/phonet.h
+++ b/include/net/phonet/phonet.h
@@ -45,6 +45,7 @@ struct pn_sock {
 extern const struct proto_ops phonet_dgram_ops;
 
 struct sock *pn_find_sock_by_sa(const struct sockaddr_pn *sa);
+void phonet_get_local_port_range(int *min, int *max);
 void pn_sock_hash(struct sock *sk);
 void pn_sock_unhash(struct sock *sk);
 int pn_sock_get_port(struct sock *sk, unsigned short sport);
@@ -93,6 +94,8 @@ int phonet_proto_register(int protocol, struct phonet_protocol *pp);
 void phonet_proto_unregister(int protocol, struct phonet_protocol *pp);
 
 void phonet_socket_init(void);
+int phonet_sysctl_init(void);
+void phonet_sysctl_exit(void);
 void phonet_netlink_register(void);
 int isi_register(void);
 void isi_unregister(void);
diff --git a/net/phonet/Makefile b/net/phonet/Makefile
index d218abc..ae9c3ed 100644
--- a/net/phonet/Makefile
+++ b/net/phonet/Makefile
@@ -5,4 +5,5 @@ phonet-objs := \
 	pn_netlink.o \
 	socket.o \
 	datagram.o \
+	sysctl.o \
 	af_phonet.o
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index 2593d9c..c18664d 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -367,6 +367,7 @@ static int __init phonet_init(void)
 	}
 
 	dev_add_pack(&phonet_packet_type);
+	phonet_sysctl_init();
 ...
From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

Common global definitions for Phonet.

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 include/linux/if_ether.h  |    1 +
 include/linux/if_phonet.h |   14 +++++
 include/linux/phonet.h    |  133 +++++++++++++++++++++++++++++++++++++++++++++
 include/linux/rtnetlink.h |    4 ++
 include/linux/socket.h    |    4 +-
 net/core/sock.c           |    9 ++-
 6 files changed, 161 insertions(+), 4 deletions(-)
 create mode 100644 include/linux/if_phonet.h
 create mode 100644 include/linux/phonet.h

diff --git a/include/linux/if_ether.h b/include/linux/if_ether.h
index 5028e0b..723a1c5 100644
--- a/include/linux/if_ether.h
+++ b/include/linux/if_ether.h
@@ -100,6 +100,7 @@
 #define ETH_P_ECONET	0x0018		/* Acorn Econet			*/
 #define ETH_P_HDLC	0x0019		/* HDLC frames			*/
 #define ETH_P_ARCNET	0x001A		/* 1A for ArcNet :-)            */
+#define ETH_P_PHONET	0x00F5		/* Nokia Phonet frames          */
 
 /*
  *	This is an Ethernet frame header.
diff --git a/include/linux/if_phonet.h b/include/linux/if_phonet.h
new file mode 100644
index 0000000..22df25f
--- /dev/null
+++ b/include/linux/if_phonet.h
@@ -0,0 +1,14 @@
+/*
+ * File: if_phonet.h
+ *
+ * Phonet interface kernel definitions
+ *
+ * Copyright (C) 2008 Nokia Corporation. All rights reserved.
+ */
+
+#define PHONET_HEADER_LEN	8	/* Phonet header length */
+
+#define PHONET_MIN_MTU		6
+/* 6 bytes header + 65535 bytes payload */
+#define PHONET_MAX_MTU		65541
+#define PHONET_DEV_MTU		PHONET_MAX_MTU
diff --git a/include/linux/phonet.h b/include/linux/phonet.h
new file mode 100644
index 0000000..000b6d7
--- /dev/null
+++ b/include/linux/phonet.h
@@ -0,0 +1,133 @@
+/**
+ * file phonet.h
+ *
+ * Phonet sockets kernel interface
+ *
+ * Copyright (C) 2008 Nokia Corporation. All rights reserved.
+ *
+ * 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.
+ ...
From: Simon Horman
Date: Tuesday, September 16, 2008 - 9:31 pm

I beleive that the prefered style is to use u8 and friends for internal kernel
structures and __u8 and friends for ones that are exported to userspace.

-- 
Simon Horman
  VA Linux Systems Japan K.K., Sydney, Australia Satellite Office
  H: www.vergenet.net/~horms/             W: www.valinux.co.jp/en

--

From: Rémi
Date: Wednesday, September 17, 2008 - 4:05 am

Now, that explains things. I'll fix all of these, thanks.

-- 
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
--

From: Rémi Denis-Courmont
Date: Tuesday, September 16, 2008 - 8:08 am

Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
---
 net/phonet/Kconfig  |   11 +++++++++++
 net/phonet/Makefile |    3 +++
 2 files changed, 14 insertions(+), 0 deletions(-)
 create mode 100644 net/phonet/Kconfig
 create mode 100644 net/phonet/Makefile

diff --git a/net/phonet/Kconfig b/net/phonet/Kconfig
new file mode 100644
index 0000000..02f8921
--- /dev/null
+++ b/net/phonet/Kconfig
@@ -0,0 +1,11 @@
+#
+# Phonet protocol
+#
+
+config PHONET
+	tristate "Phonet protocols family"
+	help
+	  Phonet is a communication protocol used by Nokia modems.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called phonet. If unsure, say N.
diff --git a/net/phonet/Makefile b/net/phonet/Makefile
new file mode 100644
index 0000000..4ced746
--- /dev/null
+++ b/net/phonet/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_PHONET) += phonet.o
+
+phonet-objs :=
-- 
1.5.4.3

--

From: Arnaldo Carvalho de Melo
Date: Tuesday, September 16, 2008 - 9:06 am

I think you could expand this a bit, no? Telling in which platforms this
would be used, i.e. nokia devices such as the N8x0 and not on a desktop
with a Nokia modem attached, etc.

Recently there were complaints about Kconfig help entries being too
terse, lets not add more of these.

- Arnaldo
--

From: Marcel Holtmann
Date: Tuesday, September 16, 2008 - 1:09 pm

We are using PhoNet over Bluetooth and IrDA inside the Gnokii project
and if we have a common PhoNet stack inside the Linux kernel that is
supported by Nokia, I do wanna use that. What are your plans for this?

Regards

Marcel


--

From: Rémi
Date: Wednesday, September 17, 2008 - 6:52 am

Hello,


Our current plan is to add GPRS data support to the Maemo Software platform. 
As the Nokia modems talk PhoNet, we plan to use this PhoNet stack to control 
GPRS functionality and to carry IP datagrams. Underneath the PhoNet stack, a 
Linux network device driver would be required. In our case, Carlos Chinea is 
publishing the OMAP SSI bus, on linux-omap.

If I understand correctly, you want to use PhoNet with S40 and/or Symbian/S60 
phones. The architecture of the PhoNet stack allows this - running on a Linux 
PC. Additional network device drivers would be needed to support the IrDA and 
Bluetooth link-layers. We are investigating the possibility to contribute 
other drivers in the future, but we have no immediate plans to do so.

Best regards,

-- 
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
--

From: Dan Williams
Date: Tuesday, September 16, 2008 - 9:15 pm

Do you have any documentation or examples of how userspace uses this
interface?  I'm starting to see a proliferation of methods by which
userspace now has to talk to cellular modems and I'd like to keep a
handle on them, despite the fact that they all pretty much do the same
thing and thus you'd think they'd expose about the same interface...


--

From: Rémi
Date: Friday, September 19, 2008 - 12:25 am

Hello,


On top of this patchset, a modem-to-Linux congestion control protocol, and of 
course, a netif would be needed:

 +--------------+ 
 | TCP/IP stack |
 +--------------+
 |  GPRS netif  | (point-to-point IP network interface)
 +--------------+
 | Phonet pipe  | (PF_PHONET, SOCK_SEQPACKET)
 +--------------+
 | Phonet stack | <--- this patchset
 +--------------+ 
 |  HW driver   | <--- sent to linux-omap
 +--------------+

I still need to polish the Phonet pipe and GPRS netif code.

This is somewhat similar to the UDP-encapsulation already in the kernel (L2TP, 
IPsec). In userland, that would look something like:

 int lfd, fd, val = PNPIPE_ENCAP_IP, ifindex;
 lfd = socket(PF_PHONET, SOCK_SEQPACKET, 0);
 listen(lfd, 1);
 /* Wait for modem */
 fd = accept(lfd, NULL, NULL);
 setsockopt(fd, SOL_PNPIPE, PNPIPE_ENCAP, &val, sizeof(val));
 getsockopt(fd, SOL_PNPIPE, PNPIPE_IFINDEX, &ifindex, sizeof(ifindex));
 printf("Created GPRS interface %s\n", if_indextoname(ifindex, buf));
 /* Configure and use IP interface */
 close(fd);
 printf("Destroyed GPRS interface\n");

I am all for using a more generic and/or cleaner userland API if there is a 

Regards,

-- 
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
--

Previous thread: [PATCH] hso reset_resume patch by Denis Joseph Barrow on Tuesday, September 16, 2008 - 7:52 am. (1 message)

Next thread: [PATCH] ipvs: change some __constant_htons() to htons() by Brian Haley on Tuesday, September 16, 2008 - 8:11 am. (3 messages)