* [PATCH 00/14] [RFC] Phonet protocol stack
@ 2008-09-16 14:57 Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 01/14] Phonet global definitions Rémi Denis-Courmont
` (15 more replies)
0 siblings, 16 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 14:57 UTC (permalink / raw)
To: netdev
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
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH 01/14] Phonet global definitions
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-17 4:31 ` Simon Horman
2008-09-16 15:08 ` [PATCH 02/14] Phonet: add CONFIG_PHONET Rémi Denis-Courmont
` (14 subsequent siblings)
15 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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.
+ *
+ * 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 LINUX_PHONET_H
+#define LINUX_PHONET_H
+
+/* Automatic protocol selection */
+#define PN_PROTO_TRANSPORT 0
+/* Phonet datagram socket */
+#define PN_PROTO_PHONET 1
+#define PHONET_NPROTO 2
+
+#define PNADDR_ANY 0
+#define PNPORT_RESOURCE_ROUTING 0
+
+/* Phonet protocol header */
+struct phonethdr {
+ uint8_t rdev;
+ uint8_t sdev;
+ uint8_t function;
+ uint16_t length;
+ uint8_t robj;
+ uint8_t sobj;
+} __attribute__((packed));
+
+/* Phonet message */
+struct phonetmsg {
+ struct phonethdr ph;
+ uint8_t data[0];
+};
+
+/* Phonet socket address structure */
+struct sockaddr_pn {
+ sa_family_t spn_family;
+ uint8_t spn_obj;
+ uint8_t spn_dev;
+ uint8_t spn_resource;
+ uint8_t spn_zero[sizeof(struct sockaddr)
+ - sizeof(sa_family_t) - 3 * sizeof(uint8_t)];
+} __attribute__ ((packed));
+
+static inline uint16_t pn_object(uint8_t addr, uint16_t port)
+{
+ return (addr << 8) | (port & 0x3ff);
+}
+
+static inline uint8_t pn_obj(uint16_t handle)
+{
+ return handle & 0xff;
+}
+
+static inline uint8_t pn_dev(uint16_t handle)
+{
+ return handle >> 8;
+}
+
+static inline uint16_t pn_port(uint16_t handle)
+{
+ return handle & 0x3ff;
+}
+
+static inline uint8_t pn_addr(uint16_t handle)
+{
+ return (handle >> 8) & 0xfc;
+}
+
+static inline void pn_sockaddr_set_addr(struct sockaddr_pn *spn, uint8_t addr)
+{
+ spn->spn_dev &= 0x03;
+ spn->spn_dev |= addr & 0xfc;
+}
+
+static inline void pn_sockaddr_set_port(struct sockaddr_pn *spn,
+ uint16_t port)
+{
+ spn->spn_dev &= 0xfc;
+ spn->spn_dev |= (port >> 8) & 0x03;
+ spn->spn_obj = port & 0xff;
+}
+
+static inline void pn_sockaddr_set_object(struct sockaddr_pn *spn,
+ uint16_t handle)
+{
+ spn->spn_dev = pn_dev(handle);
+ spn->spn_obj = pn_obj(handle);
+}
+
+static inline void pn_sockaddr_set_resource(struct sockaddr_pn *spn,
+ uint8_t resource)
+{
+ spn->spn_resource = resource;
+}
+
+static inline uint8_t pn_sockaddr_get_addr(const struct sockaddr_pn *spn)
+{
+ return spn->spn_dev & 0xfc;
+}
+
+static inline uint16_t pn_sockaddr_get_port(const struct sockaddr_pn *spn)
+{
+ return ((spn->spn_dev & 0x03) << 8) | spn->spn_obj;
+}
+
+static inline uint16_t pn_sockaddr_get_object(const struct sockaddr_pn *spn)
+{
+ return pn_object(spn->spn_dev, spn->spn_obj);
+}
+
+static inline uint8_t pn_sockaddr_get_resource(const struct sockaddr_pn *spn)
+{
+ return spn->spn_resource;
+}
+
+#endif
diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
index ca643b1..2b3d51c 100644
--- a/include/linux/rtnetlink.h
+++ b/include/linux/rtnetlink.h
@@ -582,6 +582,10 @@ enum rtnetlink_groups {
#define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE
RTNLGRP_ND_USEROPT,
#define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT
+ RTNLGRP_PHONET_IFADDR,
+#define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR
+ RTNLGRP_PHONET_ROUTE,
+#define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE
__RTNLGRP_MAX
};
#define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
diff --git a/include/linux/socket.h b/include/linux/socket.h
index dc5086f..818ca33 100644
--- a/include/linux/socket.h
+++ b/include/linux/socket.h
@@ -190,7 +190,8 @@ struct ucred {
#define AF_IUCV 32 /* IUCV sockets */
#define AF_RXRPC 33 /* RxRPC sockets */
#define AF_ISDN 34 /* mISDN sockets */
-#define AF_MAX 35 /* For now.. */
+#define AF_PHONET 35 /* Phonet sockets */
+#define AF_MAX 36 /* For now.. */
/* Protocol families, same as address families. */
#define PF_UNSPEC AF_UNSPEC
@@ -227,6 +228,7 @@ struct ucred {
#define PF_IUCV AF_IUCV
#define PF_RXRPC AF_RXRPC
#define PF_ISDN AF_ISDN
+#define PF_PHONET AF_PHONET
#define PF_MAX AF_MAX
/* Maximum queue length specifiable by listen. */
diff --git a/net/core/sock.c b/net/core/sock.c
index d823978..4ce2145 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -154,7 +154,8 @@ static const char *af_family_key_strings[AF_MAX+1] = {
"sk_lock-AF_PPPOX" , "sk_lock-AF_WANPIPE" , "sk_lock-AF_LLC" ,
"sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" ,
"sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" ,
- "sk_lock-AF_RXRPC" , "sk_lock-AF_MISDN" , "sk_lock-AF_MAX"
+ "sk_lock-AF_RXRPC" , "sk_lock-AF_MISDN" , "sk_lock-AF_PHONET" ,
+ "sk_lock-AF_MAX"
};
static const char *af_family_slock_key_strings[AF_MAX+1] = {
"slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" ,
@@ -168,7 +169,8 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = {
"slock-AF_PPPOX" , "slock-AF_WANPIPE" , "slock-AF_LLC" ,
"slock-27" , "slock-28" , "slock-AF_CAN" ,
"slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" ,
- "slock-AF_RXRPC" , "slock-AF_MISDN" , "slock-AF_MAX"
+ "slock-AF_RXRPC" , "slock-AF_MISDN" , "slock-AF_PHONET" ,
+ "slock-AF_MAX"
};
static const char *af_family_clock_key_strings[AF_MAX+1] = {
"clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" ,
@@ -182,7 +184,8 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = {
"clock-AF_PPPOX" , "clock-AF_WANPIPE" , "clock-AF_LLC" ,
"clock-27" , "clock-28" , "clock-AF_CAN" ,
"clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" ,
- "clock-AF_RXRPC" , "clock-AF_MISDN" , "clock-AF_MAX"
+ "clock-AF_RXRPC" , "clock-AF_MISDN" , "clock-AF_PHONET" ,
+ "clock-AF_MAX"
};
#endif
--
1.5.4.3
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 02/14] Phonet: add CONFIG_PHONET
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 01/14] Phonet global definitions Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 16:06 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 03/14] Phonet: build the net/phonet/ directory Rémi Denis-Courmont
` (13 subsequent siblings)
15 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 03/14] Phonet: build the net/phonet/ directory
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 01/14] Phonet global definitions Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 02/14] Phonet: add CONFIG_PHONET Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 16:06 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 04/14] Phonet: PF_PHONET protocol family support Rémi Denis-Courmont
` (12 subsequent siblings)
15 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 04/14] Phonet: PF_PHONET protocol family support
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (2 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 03/14] Phonet: build the net/phonet/ directory Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 16:17 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 05/14] Phonet: network device and address handling Rémi Denis-Courmont
` (11 subsequent siblings)
15 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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 = pn_object(ph->sdev, ph->sobj);
+
+ sa->spn_family = AF_PHONET;
+ pn_sockaddr_set_object(sa, obj);
+ pn_sockaddr_set_resource(sa, ph->function);
+ memset(sa->spn_zero, 0, sizeof(sa->spn_zero));
+}
+
+static inline
+void pn_skb_get_dst_sockaddr(struct sk_buff *skb, struct sockaddr_pn *sa)
+{
+ struct phonethdr *ph = pn_hdr(skb);
+ uint16_t obj = pn_object(ph->rdev, ph->robj);
+
+ sa->spn_family = AF_PHONET;
+ pn_sockaddr_set_object(sa, obj);
+ pn_sockaddr_set_resource(sa, ph->function);
+ memset(sa->spn_zero, 0, sizeof(sa->spn_zero));
+}
+
+/* Protocols in Phonet protocol family. */
+struct phonet_protocol {
+ struct proto *prot;
+ int sock_type;
+};
+
+int phonet_proto_register(int protocol, struct phonet_protocol *pp);
+void phonet_proto_unregister(int protocol, struct phonet_protocol *pp);
+
+#endif
diff --git a/net/phonet/Makefile b/net/phonet/Makefile
index 4ced746..5dbff68 100644
--- a/net/phonet/Makefile
+++ b/net/phonet/Makefile
@@ -1,3 +1,4 @@
obj-$(CONFIG_PHONET) += phonet.o
-phonet-objs :=
+phonet-objs := \
+ af_phonet.o
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
new file mode 100644
index 0000000..ed66a81
--- /dev/null
+++ b/net/phonet/af_phonet.c
@@ -0,0 +1,218 @@
+/*
+ * File: af_phonet.c
+ *
+ * Phonet protocols family
+ *
+ * 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 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/module.h>
+#include <asm/unaligned.h>
+#include <net/sock.h>
+
+#include <linux/if_phonet.h>
+#include <linux/phonet.h>
+#include <net/phonet/phonet.h>
+
+static struct net_proto_family phonet_proto_family;
+static struct phonet_protocol *phonet_proto_get(int protocol);
+static inline void phonet_proto_put(struct phonet_protocol *pp);
+
+/* protocol family functions */
+
+static int pn_socket_create(struct net *net, struct socket *sock, int protocol)
+{
+ struct phonet_protocol *pnp;
+ int err;
+
+ if (net != &init_net)
+ return -EAFNOSUPPORT;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ if (protocol == 0) {
+ /* Default protocol selection */
+ switch (sock->type) {
+ case SOCK_RDM:
+ case SOCK_DGRAM:
+ protocol = PN_PROTO_PHONET;
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+ }
+
+ pnp = phonet_proto_get(protocol);
+ if (pnp == NULL)
+ return -EPROTONOSUPPORT;
+ if (sock->type != pnp->sock_type &&
+ (protocol != PN_PROTO_PHONET || sock->type != SOCK_RDM)) {
+ err = -EPROTONOSUPPORT;
+ goto out;
+ }
+
+ /* TODO: create and init the struct sock */
+ err = -EPROTONOSUPPORT;
+
+out:
+ phonet_proto_put(pnp);
+ return err;
+}
+
+static struct net_proto_family phonet_proto_family = {
+ .family = AF_PHONET,
+ .create = pn_socket_create,
+ .owner = THIS_MODULE,
+};
+
+/* packet type functions */
+
+/*
+ * Stuff received packets to associated sockets.
+ * On error, returns non-zero and releases the skb.
+ */
+static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
+ struct packet_type *pkttype,
+ struct net_device *orig_dev)
+{
+ struct phonethdr *ph;
+ struct sockaddr_pn sa;
+ u16 len;
+
+ if (dev_net(dev) != &init_net)
+ goto out;
+
+ /* check we have at least a full Phonet header */
+ if (!pskb_pull(skb, sizeof(struct phonethdr)))
+ goto out;
+
+ /* check that the advertised length is correct */
+ ph = pn_hdr(skb);
+ len = get_unaligned_be16(&ph->length);
+ if (len < 2)
+ goto out;
+ len -= 2;
+ if ((len > skb->len) || pskb_trim(skb, len))
+ goto out;
+ skb_reset_transport_header(skb);
+
+ pn_skb_get_dst_sockaddr(skb, &sa);
+ if (pn_sockaddr_get_addr(&sa) == 0)
+ goto out; /* currently, we cannot be device 0 */
+
+ /* TODO: put packets to sockets backlog */
+
+out:
+ kfree_skb(skb);
+ return NET_RX_DROP;
+}
+
+static struct packet_type phonet_packet_type = {
+ .type = __constant_htons(ETH_P_PHONET),
+ .dev = NULL,
+ .func = phonet_rcv,
+};
+
+/* Transport protocol registration */
+static struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly;
+static DEFINE_SPINLOCK(proto_tab_lock);
+
+int __init_or_module phonet_proto_register(int protocol,
+ struct phonet_protocol *pp)
+{
+ int err = 0;
+
+ if (protocol >= PHONET_NPROTO)
+ return -EINVAL;
+
+ err = proto_register(pp->prot, 1);
+ if (err)
+ return err;
+
+ spin_lock(&proto_tab_lock);
+ if (proto_tab[protocol])
+ err = -EBUSY;
+ else
+ proto_tab[protocol] = pp;
+ spin_unlock(&proto_tab_lock);
+
+ return err;
+}
+EXPORT_SYMBOL(phonet_proto_register);
+
+void phonet_proto_unregister(int protocol, struct phonet_protocol *pp)
+{
+ spin_lock(&proto_tab_lock);
+ BUG_ON(proto_tab[protocol] != pp);
+ proto_tab[protocol] = NULL;
+ spin_unlock(&proto_tab_lock);
+ proto_unregister(pp->prot);
+}
+EXPORT_SYMBOL(phonet_proto_unregister);
+
+static struct phonet_protocol *phonet_proto_get(int protocol)
+{
+ struct phonet_protocol *pp;
+
+ if (protocol >= PHONET_NPROTO)
+ return NULL;
+
+ spin_lock(&proto_tab_lock);
+ pp = proto_tab[protocol];
+ if (pp && !try_module_get(pp->prot->owner))
+ pp = NULL;
+ spin_unlock(&proto_tab_lock);
+
+ return pp;
+}
+
+static inline void phonet_proto_put(struct phonet_protocol *pp)
+{
+ module_put(pp->prot->owner);
+}
+
+/* Module registration */
+static int __init phonet_init(void)
+{
+ int err;
+
+ err = sock_register(&phonet_proto_family);
+ if (err) {
+ printk(KERN_ALERT
+ "phonet protocol family initialization failed\n");
+ return err;
+ }
+
+ dev_add_pack(&phonet_packet_type);
+ return 0;
+}
+
+static void __exit phonet_exit(void)
+{
+ sock_unregister(AF_PHONET);
+ dev_remove_pack(&phonet_packet_type);
+}
+
+module_init(phonet_init);
+module_exit(phonet_exit);
+MODULE_DESCRIPTION("Phonet protocol stack for Linux");
+MODULE_LICENSE("GPL");
--
1.5.4.3
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 05/14] Phonet: network device and address handling
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (3 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 04/14] Phonet: PF_PHONET protocol family support Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 16:41 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 06/14] Phonet: Netlink interface Rémi Denis-Courmont
` (10 subsequent siblings)
15 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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 *phonet_device_alloc(struct net_device *dev);
+struct phonet_device *__phonet_get_by_index(unsigned ifindex);
+void phonet_device_free(struct phonet_device *pnd);
+
+struct phonet_address *phonet_address_alloc(void);
+void phonet_address_add(struct list_head *list, struct phonet_address *pna);
+void phonet_address_free(struct phonet_address *pna);
+struct phonet_address *phonet_addr2addr(uint8_t addr, int mode);
+struct phonet_address *phonet_dev2addr(struct phonet_device *pnd, uint8_t addr,
+ int mode);
+
+#define PN_FIND_EXACT (1 << 0)
+
+#define MKMASK(a) ((1 << (a)) - 1)
+
+#endif
diff --git a/net/phonet/Makefile b/net/phonet/Makefile
index 5dbff68..980a386 100644
--- a/net/phonet/Makefile
+++ b/net/phonet/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_PHONET) += phonet.o
phonet-objs := \
+ pn_dev.o \
af_phonet.o
diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
index ed66a81..744b47f 100644
--- a/net/phonet/af_phonet.c
+++ b/net/phonet/af_phonet.c
@@ -31,6 +31,7 @@
#include <linux/if_phonet.h>
#include <linux/phonet.h>
#include <net/phonet/phonet.h>
+#include <net/phonet/pn_dev.h>
static struct net_proto_family phonet_proto_family;
static struct phonet_protocol *phonet_proto_get(int protocol);
@@ -202,14 +203,25 @@ static int __init phonet_init(void)
return err;
}
+ err = phonet_device_init();
+ if (err) {
+ printk(KERN_ALERT "phonet devices initialization failed\n");
+ goto unregister;
+ }
+
dev_add_pack(&phonet_packet_type);
return 0;
+
+unregister:
+ sock_unregister(AF_PHONET);
+ return err;
}
static void __exit phonet_exit(void)
{
sock_unregister(AF_PHONET);
dev_remove_pack(&phonet_packet_type);
+ phonet_device_exit();
}
module_init(phonet_init);
diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
new file mode 100644
index 0000000..cae37a6
--- /dev/null
+++ b/net/phonet/pn_dev.c
@@ -0,0 +1,233 @@
+/*
+ * File: pn_dev.c
+ *
+ * Phonet network device
+ *
+ * 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 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/net.h>
+#include <linux/netdevice.h>
+#include <linux/phonet.h>
+#include <net/sock.h>
+#include <net/phonet/pn_dev.h>
+
+static int phonet_device_notify(struct notifier_block *self, unsigned long what,
+ void *dev);
+
+/* when accessing, remember to lock with spin_lock(&pndevs.lock); */
+struct phonet_device_list pndevs;
+
+static struct notifier_block phonet_device_notifier = {
+ .notifier_call = &phonet_device_notify,
+ .priority = 0,
+};
+
+/* initialise Phonet device list */
+int phonet_device_init(void)
+{
+ INIT_LIST_HEAD(&pndevs.list);
+ spin_lock_init(&pndevs.lock);
+ register_netdevice_notifier(&phonet_device_notifier);
+
+ return 0;
+}
+
+void phonet_device_exit(void)
+{
+ struct list_head *ptr;
+
+ rtnl_unregister_all(PF_PHONET);
+ rtnl_lock();
+ spin_lock_bh(&pndevs.lock);
+
+ for (ptr = pndevs.list.next; ptr != &pndevs.list;
+ ptr = pndevs.list.next) {
+ struct phonet_device *pnd = list_entry(ptr,
+ struct phonet_device, list);
+ phonet_device_free(pnd);
+ }
+
+ spin_unlock_bh(&pndevs.lock);
+ rtnl_unlock();
+ unregister_netdevice_notifier(&phonet_device_notifier);
+}
+
+struct phonet_address *phonet_address_alloc(void)
+{
+ struct phonet_address *pna;
+
+ pna = kmalloc(sizeof(struct phonet_address), GFP_KERNEL);
+
+ if (pna == NULL)
+ return NULL;
+
+ INIT_LIST_HEAD(&pna->list);
+
+ return pna;
+}
+
+/* add Phonet address to list */
+void phonet_address_add(struct list_head *list, struct phonet_address *pna)
+{
+ list_add(&pna->list, list);
+}
+
+/* remove Phonet address from list and free it */
+void phonet_address_free(struct phonet_address *pna)
+{
+ list_del(&pna->list);
+ kfree(pna);
+}
+
+/* Allocate new Phonet device. */
+struct phonet_device *phonet_device_alloc(struct net_device *dev)
+{
+ struct phonet_device *pnd;
+
+ pnd = kmalloc(sizeof(struct phonet_device), GFP_ATOMIC);
+
+ if (pnd == NULL)
+ return NULL;
+
+ INIT_LIST_HEAD(&pnd->own);
+ pnd->netdev = dev;
+ list_add(&pnd->list, &pndevs.list);
+ return pnd;
+}
+
+struct phonet_device *__phonet_get_by_index(unsigned ifindex)
+{
+ struct list_head *p;
+
+ list_for_each(p, &pndevs.list) {
+ struct phonet_device *pnd;
+
+ pnd = list_entry(p, struct phonet_device, list);
+ BUG_ON(!pnd->netdev);
+
+ if (pnd->netdev->ifindex == ifindex)
+ return pnd;
+ }
+ return NULL;
+}
+
+void phonet_device_free(struct phonet_device *pnd)
+{
+ struct list_head *ptr;
+
+ /* remove device from list */
+ list_del(&pnd->list);
+
+ for (ptr = pnd->own.next; ptr != &pnd->own; ptr = pnd->own.next) {
+ struct phonet_address *pna =
+ list_entry(ptr, struct phonet_address, list);
+ phonet_address_free(pna);
+ }
+
+ kfree(pnd);
+}
+
+/*
+ * Find the address from the device's address list having the given address
+ */
+struct phonet_address *phonet_dev2addr(struct phonet_device *pnd,
+ uint8_t addr, int mode)
+{
+ struct list_head *list = &pnd->own, *ptr;
+ struct phonet_address *best = NULL;
+
+ for (ptr = list->next; ptr != list; ptr = ptr->next) {
+ struct phonet_address *pna =
+ list_entry(ptr, struct phonet_address, list);
+
+ if (mode & PN_FIND_EXACT) {
+ /* try to find exact address */
+ if (pna->addr == addr) {
+ best = pna;
+ break;
+ }
+ } else if (best == NULL ||
+ best->prefix < pna->prefix) {
+ if ((pna->addr & MKMASK(pna->prefix)) ==
+ (addr & MKMASK(pna->prefix))) {
+ best = pna;
+ }
+ }
+ }
+
+ return best;
+}
+
+/*
+ * Find the device having a given address (remember locking!!)
+ */
+struct phonet_address *phonet_addr2addr(uint8_t addr, int mode)
+{
+ struct list_head *ptr;
+ struct phonet_address *best = NULL;
+
+ for (ptr = pndevs.list.next; ptr != &pndevs.list; ptr = ptr->next) {
+ struct phonet_address *pna = NULL;
+ struct phonet_device *pnd =
+ list_entry(ptr, struct phonet_device, list);
+
+ /* Don't allow unregistering devices! */
+ if ((pnd->netdev->reg_state != NETREG_REGISTERED) ||
+ ((pnd->netdev->flags & IFF_UP)) != IFF_UP)
+ continue;
+
+ pna = phonet_dev2addr(pnd, addr, mode);
+
+ if (pna != NULL) {
+ if (best == NULL || best->prefix < pna->prefix)
+ best = pna;
+ }
+ }
+
+ return best;
+}
+
+/* notify Phonet of device events */
+static int phonet_device_notify(struct notifier_block *self, unsigned long what,
+ void *_dev)
+{
+ struct net_device *dev = _dev;
+ struct phonet_device *pnd;
+
+ spin_lock_bh(&pndevs.lock);
+ pnd = __phonet_get_by_index(dev->ifindex);
+
+ switch (what) {
+ case NETDEV_UNREGISTER:
+ if (pnd == NULL)
+ break;
+ phonet_device_free(pnd);
+ break;
+ default:
+ break;
+ }
+
+ spin_unlock_bh(&pndevs.lock);
+
+ return 0;
+
+}
--
1.5.4.3
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 06/14] Phonet: Netlink interface
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (4 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 05/14] Phonet: network device and address handling Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 07/14] Phonet: common socket glue Rémi Denis-Courmont
` (9 subsequent siblings)
15 siblings, 0 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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 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/netlink.h>
+#include <linux/phonet.h>
+#include <net/sock.h>
+#include <net/phonet/pn_dev.h>
+
+static int fill_addr(struct sk_buff *skb, struct phonet_address *ifaddr,
+ u32 pid, u32 seq, int event);
+
+static void rtmsg_notify(int event, struct phonet_address *pna)
+{
+ struct sk_buff *skb;
+ int err = -ENOBUFS;
+
+ skb = nlmsg_new(NLMSG_ALIGN(sizeof(struct ifaddrmsg)) +
+ nla_total_size(1), GFP_KERNEL);
+ if (skb == NULL)
+ goto errout;
+ err = fill_addr(skb, pna, 0, 0, event);
+ if (err < 0) {
+ WARN_ON(err == -EMSGSIZE);
+ kfree_skb(skb);
+ goto errout;
+ }
+ err = rtnl_notify(skb, dev_net(pna->pnd->netdev), 0,
+ RTNLGRP_PHONET_IFADDR, NULL, GFP_KERNEL);
+errout:
+ if (err < 0)
+ rtnl_set_sk_err(dev_net(pna->pnd->netdev),
+ RTNLGRP_PHONET_IFADDR, err);
+}
+
+static int newaddr_doit(struct sk_buff *skb, struct nlmsghdr *nlm, void *attr)
+{
+ struct rtattr **rta = attr;
+ struct ifaddrmsg *ifm = NLMSG_DATA(nlm);
+ struct net_device *dev;
+ struct phonet_device *pnd;
+ struct phonet_address *pna;
+ uint8_t pnaddr;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ ASSERT_RTNL();
+
+ if (rta[IFA_LOCAL - 1] == NULL)
+ return -EINVAL;
+
+ dev = __dev_get_by_index(&init_net, ifm->ifa_index);
+ if (dev == NULL)
+ return -ENODEV;
+
+ if (ifm->ifa_prefixlen > 8)
+ return -EINVAL;
+
+ memcpy((void *)&pnaddr, RTA_DATA(rta[IFA_LOCAL - 1]), 1);
+
+ spin_lock_bh(&pndevs.lock);
+ if (phonet_addr2addr(pnaddr, PN_FIND_EXACT)) {
+ spin_unlock_bh(&pndevs.lock);
+ return -EADDRINUSE;
+ }
+ pnd = __phonet_get_by_index(ifm->ifa_index);
+ if (pnd == NULL)
+ pnd = phonet_device_alloc(dev);
+ spin_unlock_bh(&pndevs.lock);
+ if (pnd == NULL)
+ return -ENOMEM;
+
+ pna = phonet_address_alloc();
+ if (pna == NULL) {
+ spin_lock_bh(&pndevs.lock);
+ if (list_empty(&pnd->own))
+ phonet_device_free(pnd);
+ spin_unlock_bh(&pndevs.lock);
+ return -ENOMEM;
+ }
+ /*
+ * Now we have a Phonet device where the already allocated address
+ * needs to be added to. Address manipulation is already protected
+ * by rtnl_lock, so pndevs.lock isn't needed all the time.
+ */
+ pna->pnd = pnd;
+ pna->addr = pnaddr;
+ pna->prefix = ifm->ifa_prefixlen;
+
+ spin_lock_bh(&pndevs.lock);
+ phonet_address_add(&pnd->own, pna);
+ spin_unlock_bh(&pndevs.lock);
+
+ rtmsg_notify(RTM_NEWADDR, pna);
+
+ return 0;
+}
+
+static int deladdr_doit(struct sk_buff *skb, struct nlmsghdr *nlm, void *attr)
+{
+ struct rtattr **rta = attr;
+ struct ifaddrmsg *ifm = NLMSG_DATA(nlm);
+ struct phonet_address *pna;
+ struct phonet_device *pnd = NULL;
+ int err;
+ uint8_t pnaddr;
+
+ if (!capable(CAP_SYS_ADMIN))
+ return -EPERM;
+
+ ASSERT_RTNL();
+
+ if (rta[IFA_LOCAL - 1] == NULL)
+ return -EINVAL;
+
+ memcpy((void *)&pnaddr, RTA_DATA(rta[IFA_LOCAL - 1]), 1);
+
+ spin_lock_bh(&pndevs.lock);
+ err = -ENODEV;
+ pnd = __phonet_get_by_index(ifm->ifa_index);
+ if (!pnd)
+ goto out;
+
+ pna = phonet_dev2addr(pnd, pnaddr, PN_FIND_EXACT);
+ if (!pna)
+ goto out;
+
+ phonet_address_free(pna);
+ if (list_empty(&pnd->own))
+ phonet_device_free(pnd);
+ spin_unlock_bh(&pndevs.lock);
+ rtmsg_notify(RTM_DELADDR, pna);
+ return 0;
+
+out:
+ spin_unlock_bh(&pndevs.lock);
+ return err;
+}
+
+static int fill_addr(struct sk_buff *skb, struct phonet_address *ifaddr,
+ u32 pid, u32 seq, int event)
+{
+ struct ifaddrmsg *ifm;
+ struct nlmsghdr *nlh;
+ unsigned int orig_len = skb->len;
+
+ nlh = NLMSG_PUT(skb, pid, seq, event, sizeof(struct ifaddrmsg));
+ ifm = NLMSG_DATA(nlh);
+ ifm->ifa_family = AF_PHONET;
+ ifm->ifa_prefixlen = ifaddr->prefix;
+ ifm->ifa_flags = IFA_F_PERMANENT;
+ ifm->ifa_scope = RT_SCOPE_HOST;
+ ifm->ifa_index = ifaddr->pnd->netdev->ifindex;
+ RTA_PUT(skb, IFA_LOCAL, 1, &ifaddr->addr);
+ nlh->nlmsg_len = skb->len - orig_len;
+
+ return 0;
+
+nlmsg_failure:
+rtattr_failure:
+ skb_trim(skb, orig_len);
+
+ return -1;
+}
+
+static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
+{
+ struct list_head *ptr;
+ int dev_idx = 0, addr_idx = 0;
+ int dev_start_idx, addr_start_idx;
+
+ dev_start_idx = cb->args[0];
+ addr_start_idx = cb->args[1];
+
+ spin_lock_bh(&pndevs.lock);
+
+ for (ptr = pndevs.list.next; ptr != &pndevs.list;
+ ptr = ptr->next, dev_idx++) {
+ struct list_head *ptr2;
+ struct phonet_device *pnd =
+ list_entry(ptr, struct phonet_device, list);
+
+ if (dev_idx < dev_start_idx)
+ continue;
+ else if (dev_idx > dev_start_idx)
+ addr_start_idx = 0;
+
+ addr_idx = 0;
+
+ for (ptr2 = pnd->own.next; ptr2 != &pnd->own;
+ ptr2 = ptr2->next, addr_idx++) {
+ struct phonet_address *pna =
+ list_entry(ptr2, struct phonet_address, list);
+
+ if (addr_idx < addr_start_idx)
+ continue;
+
+ if (fill_addr(skb, pna, NETLINK_CB(cb->skb).pid,
+ cb->nlh->nlmsg_seq, RTM_NEWADDR))
+ goto out;
+ }
+ }
+
+out:
+ spin_unlock_bh(&pndevs.lock);
+ cb->args[0] = dev_idx;
+ cb->args[1] = addr_idx;
+
+ return skb->len;
+}
+
+void __init phonet_netlink_register(void)
+{
+ rtnl_register(PF_PHONET, RTM_NEWADDR, newaddr_doit, NULL);
+ rtnl_register(PF_PHONET, RTM_DELADDR, deladdr_doit, NULL);
+ rtnl_register(PF_PHONET, RTM_GETADDR, NULL, getaddr_dumpit);
+}
--
1.5.4.3
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 07/14] Phonet: common socket glue
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (5 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 06/14] Phonet: Netlink interface Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 16:50 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 08/14] Phonet: receive path socket lookup Rémi Denis-Courmont
` (8 subsequent siblings)
15 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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 +3,5 @@ obj-$(CONFIG_PHONET) += phonet.o
phonet-objs := \
pn_dev.o \
pn_netlink.o \
+ socket.o \
af_phonet.o
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
new file mode 100644
index 0000000..0e28327
--- /dev/null
+++ b/net/phonet/socket.c
@@ -0,0 +1,312 @@
+/*
+ * File: socket.c
+ *
+ * Phonet sockets
+ *
+ * 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 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/net.h>
+#include <net/sock.h>
+#include <net/tcp_states.h>
+
+#include <linux/phonet.h>
+#include <net/phonet/phonet.h>
+#include <net/phonet/pn_dev.h>
+
+static int pn_socket_release(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+
+ if (sk) {
+ sock->sk = NULL;
+ sk->sk_prot->close(sk, 0);
+ }
+ return 0;
+}
+
+static struct {
+ struct hlist_head hlist;
+ spinlock_t lock;
+} pnsocks;
+
+/*
+ * Find address based on socket address, match only certain fields.
+ * Also grab sock if it was found. Remember to sock_put it later.
+ */
+struct sock *pn_find_sock_by_sa(const struct sockaddr_pn *spn)
+{
+ struct hlist_node *node;
+ struct sock *sknode;
+ struct sock *rval = NULL;
+ uint16_t obj = pn_sockaddr_get_object(spn);
+ uint8_t res = spn->spn_resource;
+
+ spin_lock_bh(&pnsocks.lock);
+
+ sk_for_each(sknode, node, &pnsocks.hlist) {
+ struct pn_sock *pn = pn_sk(sknode);
+ BUG_ON(!pn->sobject); /* unbound socket */
+
+ if (pn_port(obj)) {
+ /* Look up socket by port */
+ if (pn_port(pn->sobject) != pn_port(obj))
+ continue;
+ } else {
+ /* If port is zero, look up by resource */
+ if (pn->resource != res)
+ continue;
+ }
+ if (pn_addr(pn->sobject)
+ && pn_addr(pn->sobject) != pn_addr(obj))
+ continue;
+
+ rval = sknode;
+ sock_hold(sknode);
+ break;
+ }
+
+ spin_unlock_bh(&pnsocks.lock);
+
+ return rval;
+
+}
+
+void pn_sock_hash(struct sock *sk)
+{
+ spin_lock_bh(&pnsocks.lock);
+ sk_add_node(sk, &pnsocks.hlist);
+ spin_unlock_bh(&pnsocks.lock);
+}
+EXPORT_SYMBOL(pn_sock_hash);
+
+void pn_sock_unhash(struct sock *sk)
+{
+ spin_lock_bh(&pnsocks.lock);
+ sk_del_node_init(sk);
+ spin_unlock_bh(&pnsocks.lock);
+}
+EXPORT_SYMBOL(pn_sock_unhash);
+
+static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
+{
+ struct sock *sk = sock->sk;
+ struct pn_sock *pn = pn_sk(sk);
+ struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
+ int err;
+ uint16_t handle;
+ uint8_t saddr;
+
+ if (sk->sk_prot->bind)
+ return sk->sk_prot->bind(sk, addr, len);
+
+ if (len < sizeof(struct sockaddr_pn))
+ return -EINVAL;
+ if (spn->spn_family != AF_PHONET)
+ return -EAFNOSUPPORT;
+
+ handle = pn_sockaddr_get_object((struct sockaddr_pn *)addr);
+ saddr = pn_addr(handle);
+ if (saddr) {
+ struct phonet_address *pna;
+
+ spin_lock_bh(&pndevs.lock);
+ pna = phonet_addr2addr(pn_addr(handle), PN_FIND_EXACT);
+ spin_unlock_bh(&pndevs.lock);
+ if (pna == NULL)
+ return -EADDRNOTAVAIL;
+ }
+
+ lock_sock(sk);
+ if (sk->sk_state != TCP_CLOSE || pn_port(pn->sobject)) {
+ err = -EINVAL; /* attempt to rebind */
+ goto out;
+ }
+ err = sk->sk_prot->get_port(sk, pn_port(handle));
+ if (err)
+ goto out;
+
+ /* get_port() sets the port, bind() sets the address if applicable */
+ pn->sobject = pn_object(saddr, pn_port(pn->sobject));
+ pn->resource = spn->spn_resource;
+
+ /* Enable RX on the socket */
+ sk->sk_prot->hash(sk);
+out:
+ release_sock(sk);
+ return err;
+}
+
+static int pn_socket_autobind(struct socket *sock)
+{
+ struct sockaddr_pn sa;
+ int err;
+
+ memset(&sa, 0, sizeof(sa));
+ sa.spn_family = AF_PHONET;
+ err = pn_socket_bind(sock, (struct sockaddr *)&sa,
+ sizeof(struct sockaddr_pn));
+ if (err != -EINVAL)
+ return err;
+ BUG_ON(!pn_port(pn_sk(sock->sk)->sobject));
+ return 0; /* socket was already bound */
+}
+
+static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,
+ int *sockaddr_len, int peer)
+{
+ struct sock *sk = sock->sk;
+ struct pn_sock *pn = pn_sk(sk);
+
+ memset(addr, 0, sizeof(struct sockaddr_pn));
+ addr->sa_family = AF_PHONET;
+ if (!peer) /* Race with bind() here is userland's problem. */
+ pn_sockaddr_set_object((struct sockaddr_pn *)addr,
+ pn->sobject);
+
+ *sockaddr_len = sizeof(struct sockaddr_pn);
+ return 0;
+}
+
+static int pn_socket_ioctl(struct socket *sock, unsigned int cmd,
+ unsigned long arg)
+{
+ struct sock *sk = sock->sk;
+ struct pn_sock *pn = pn_sk(sk);
+
+ if (cmd == SIOCPNGETOBJECT) {
+ struct phonet_address *pna;
+ uint16_t handle;
+ uint8_t rdev;
+
+ if (get_user(handle, (uint16_t __user *)arg))
+ return -EFAULT;
+
+ rdev = pn_dev(handle);
+ spin_lock_bh(&pndevs.lock);
+ pna = phonet_addr2addr(rdev, 0);
+ if (pna)
+ handle = pn_object(pna->addr, pn_port(pn->sobject));
+ spin_unlock_bh(&pndevs.lock);
+
+ if (!pna)
+ return -EHOSTUNREACH;
+ return put_user(handle, (uint16_t __user *)arg);
+ }
+
+ return sk->sk_prot->ioctl(sk, cmd, arg);
+}
+
+static int pn_socket_sendmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *m, size_t total_len)
+{
+ struct sock *sk = sock->sk;
+
+ if (pn_socket_autobind(sock))
+ return -EAGAIN;
+
+ return sk->sk_prot->sendmsg(iocb, sk, m, total_len);
+}
+
+const struct proto_ops phonet_dgram_ops = {
+ .family = AF_PHONET,
+ .owner = THIS_MODULE,
+ .release = pn_socket_release,
+ .bind = pn_socket_bind,
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .getname = pn_socket_getname,
+ .poll = datagram_poll,
+ .ioctl = pn_socket_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .setsockopt = sock_no_setsockopt,
+ .getsockopt = sock_no_getsockopt,
+#ifdef CONFIG_COMPAT
+ .compat_setsockopt = sock_no_setsockopt,
+ .compat_getsockopt = sock_no_getsockopt,
+#endif
+ .sendmsg = pn_socket_sendmsg,
+ .recvmsg = sock_common_recvmsg,
+ .mmap = sock_no_mmap,
+ .sendpage = sock_no_sendpage,
+};
+
+static DEFINE_MUTEX(port_mutex);
+
+/* allocate port for a socket */
+int pn_sock_get_port(struct sock *sk, unsigned short sport)
+{
+ static int port_cur;
+ struct pn_sock *pn = pn_sk(sk);
+ struct sockaddr_pn try_sa;
+ struct sock *tmpsk;
+
+ memset(&try_sa, 0, sizeof(struct sockaddr_pn));
+ try_sa.spn_family = AF_PHONET;
+
+ mutex_lock(&port_mutex);
+
+ if (!sport) {
+ /* search free port */
+ int port, pmin = 0x40, pmax = 0x7f;
+
+ for (port = pmin; port <= pmax; port++) {
+ port_cur++;
+ if (port_cur < pmin || port_cur > pmax)
+ port_cur = pmin;
+
+ pn_sockaddr_set_port(&try_sa, port_cur);
+ tmpsk = pn_find_sock_by_sa(&try_sa);
+ if (tmpsk == NULL) {
+ sport = port_cur;
+ goto found;
+ } else
+ sock_put(tmpsk);
+ }
+ } else {
+ /* try to find specific port */
+ pn_sockaddr_set_port(&try_sa, sport);
+ tmpsk = pn_find_sock_by_sa(&try_sa);
+ if (tmpsk == NULL)
+ /* No sock there! We can use that port... */
+ goto found;
+ else
+ sock_put(tmpsk);
+ }
+ mutex_unlock(&port_mutex);
+
+ /* the port must be in use already */
+ return -EADDRINUSE;
+
+found:
+ mutex_unlock(&port_mutex);
+ pn->sobject = pn_object(pn_addr(pn->sobject), sport);
+ return 0;
+}
+EXPORT_SYMBOL(pn_sock_get_port);
+
+void __init phonet_socket_init(void)
+{
+ INIT_HLIST_HEAD(&pnsocks.hlist);
+ spin_lock_init(&pnsocks.lock);
+}
--
1.5.4.3
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 08/14] Phonet: receive path socket lookup
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (6 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 07/14] Phonet: common socket glue Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 16:52 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 09/14] Phonet: allocate and initialize new sockets Rémi Denis-Courmont
` (7 subsequent siblings)
15 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 09/14] Phonet: allocate and initialize new sockets
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (7 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 08/14] Phonet: receive path socket lookup Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 16:53 ` Arnaldo Carvalho de Melo
2008-09-16 18:42 ` Pavel Emelyanov
2008-09-16 15:08 ` [PATCH 10/14] Phonet: Phonet datagram transport protocol Rémi Denis-Courmont
` (6 subsequent siblings)
15 siblings, 2 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 10/14] Phonet: Phonet datagram transport protocol
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (8 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 09/14] Phonet: allocate and initialize new sockets Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 17:06 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 11/14] Phonet: provide MAC header operations Rémi Denis-Courmont
` (5 subsequent siblings)
15 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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 drop;
+ }
+
+ skb_reset_transport_header(skb);
+ WARN_ON(skb_headroom(skb) & 1); /* HW assumes word alignment */
+ ph = (struct phonethdr *)skb_push(skb, sizeof(struct phonethdr));
+ skb_reset_network_header(skb);
+ ph->rdev = pn_dev(dst);
+ ph->sdev = pn_dev(src);
+ ph->function = res;
+ ph->length = __cpu_to_be16(skb->len + 2 - sizeof(*ph));
+ ph->robj = pn_obj(dst);
+ ph->sobj = pn_obj(src);
+
+ skb->protocol = __constant_htons(ETH_P_PHONET);
+ skb->priority = 0;
+ skb->dev = dev;
+
+ if (pn_addr(src) == pn_addr(dst)) {
+ skb_reset_mac_header(skb);
+ skb->pkt_type = PACKET_LOOPBACK;
+ skb_orphan(skb);
+ netif_rx_ni(skb);
+ err = 0;
+ } else {
+ err = dev_hard_header(skb, dev, ntohs(skb->protocol),
+ NULL, NULL, skb->len);
+ if (err < 0) {
+ err = -EHOSTUNREACH;
+ goto drop;
+ }
+ err = dev_queue_xmit(skb);
+ }
+
+ return err;
+drop:
+ kfree_skb(skb);
+ return err;
+}
+
+/*
+ * Create a Phonet header for the skb and send it out. Returns
+ * non-zero error code if failed. The skb is freed then.
+ */
+int pn_skb_send(struct sock *sk, struct sk_buff *skb,
+ const struct sockaddr_pn *target)
+{
+ struct net_device *dev;
+ struct phonet_address *pna = NULL;
+ struct pn_sock *pn = pn_sk(sk);
+ int err;
+ uint16_t src;
+ uint8_t addr = pn_sockaddr_get_addr(target);
+
+ spin_lock_bh(&pndevs.lock);
+ if (sk->sk_bound_dev_if) {
+ struct phonet_device *pnd;
+
+ pnd = __phonet_get_by_index(sk->sk_bound_dev_if);
+ if (pnd && (pnd->netdev->flags & IFF_UP))
+ pna = phonet_dev2addr(pnd, addr, 0);
+ } else {
+ pna = phonet_addr2addr(pn_sockaddr_get_addr(target), 0);
+ }
+
+ if (pna == NULL) {
+ spin_unlock_bh(&pndevs.lock);
+ err = -EHOSTUNREACH;
+ goto drop;
+ }
+
+ src = pn->sobject;
+ if (!pn_addr(src))
+ src = pn_object(pna->addr, pn_obj(src));
+
+ dev = pna->pnd->netdev;
+ dev_hold(dev);
+ spin_unlock_bh(&pndevs.lock);
+
+ err = pn_send(skb, dev, pn_sockaddr_get_object(target),
+ src, pn_sockaddr_get_resource(target));
+ dev_put(dev);
+ return err;
+
+drop:
+ kfree_skb(skb);
+ return err;
+}
+EXPORT_SYMBOL(pn_skb_send);
+
/* packet type functions */
/*
@@ -238,8 +339,14 @@ static int __init phonet_init(void)
dev_add_pack(&phonet_packet_type);
phonet_netlink_register();
+
+ err = isi_register();
+ if (err)
+ goto err2;
return 0;
+err2:
+ phonet_device_exit();
unregister:
sock_unregister(AF_PHONET);
return err;
@@ -247,6 +354,7 @@ unregister:
static void __exit phonet_exit(void)
{
+ isi_unregister();
sock_unregister(AF_PHONET);
dev_remove_pack(&phonet_packet_type);
phonet_device_exit();
diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
new file mode 100644
index 0000000..5d8e701
--- /dev/null
+++ b/net/phonet/datagram.c
@@ -0,0 +1,198 @@
+/*
+ * File: datagram.c
+ *
+ * Datagram (ISI) Phonet sockets
+ *
+ * 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 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/socket.h>
+#include <asm/ioctls.h>
+#include <net/sock.h>
+
+#include <linux/phonet.h>
+#include <net/phonet/phonet.h>
+
+static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb);
+
+/* associated socket ceases to exist */
+static void pn_sock_close(struct sock *sk, long timeout)
+{
+ sk_common_release(sk);
+}
+
+static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg)
+{
+ struct sk_buff *skb;
+ int answ;
+
+ switch (cmd) {
+ case SIOCINQ:
+ spin_lock_bh(&sk->sk_receive_queue.lock);
+ skb = skb_peek(&sk->sk_receive_queue);
+ answ = skb ? skb->len : 0;
+ spin_unlock_bh(&sk->sk_receive_queue.lock);
+ return put_user(answ, (int __user *)arg);
+ }
+
+ return -ENOIOCTLCMD;
+}
+
+/* Destroy socket. All references are gone. */
+static void pn_destruct(struct sock *sk)
+{
+ skb_queue_purge(&sk->sk_receive_queue);
+}
+
+static int pn_init(struct sock *sk)
+{
+ sk->sk_destruct = pn_destruct;
+ pn_sk(sk)->handler = pn_backlog_rcv;
+ return 0;
+}
+
+static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,
+ struct msghdr *msg, size_t len)
+{
+ struct sockaddr_pn *target;
+ struct sk_buff *skb;
+ int err;
+
+ if (msg->msg_flags & MSG_OOB)
+ return -EOPNOTSUPP;
+
+ if (msg->msg_name == NULL)
+ return -EDESTADDRREQ;
+
+ if (msg->msg_namelen < sizeof(struct sockaddr_pn))
+ return -EINVAL;
+
+ target = (struct sockaddr_pn *)msg->msg_name;
+ if (target->spn_family != AF_PHONET)
+ return -EAFNOSUPPORT;
+
+ skb = sock_alloc_send_skb(sk, MAX_PHONET_HEADER + len,
+ msg->msg_flags & MSG_DONTWAIT, &err);
+ if (skb == NULL)
+ return err;
+ skb_reserve(skb, MAX_PHONET_HEADER);
+
+ err = memcpy_fromiovec((void *)skb_put(skb, len), msg->msg_iov, len);
+ if (err < 0) {
+ kfree_skb(skb);
+ return err;
+ }
+
+ /*
+ * Fill in the Phonet header and
+ * finally pass the packet forwards.
+ */
+ err = pn_skb_send(sk, skb, target);
+
+ /* If ok, return len. */
+ return (err >= 0) ? len : err;
+}
+
+static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
+ struct msghdr *msg, size_t len, int noblock,
+ int flags, int *addr_len)
+{
+ struct sk_buff *skb = NULL;
+ struct sockaddr_pn sa;
+ int rval = -EOPNOTSUPP;
+ int copylen;
+
+ if (flags & MSG_OOB)
+ goto out_nofree;
+
+ if (addr_len)
+ *addr_len = sizeof(sa);
+
+ skb = skb_recv_datagram(sk, flags, noblock, &rval);
+ if (skb == NULL)
+ goto out_nofree;
+
+ pn_skb_get_src_sockaddr(skb, &sa);
+
+ copylen = skb->len;
+ if (len < copylen) {
+ msg->msg_flags |= MSG_TRUNC;
+ copylen = len;
+ }
+
+ rval = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copylen);
+ if (rval) {
+ rval = -EFAULT;
+ goto out;
+ }
+
+ rval = (flags & MSG_TRUNC) ? skb->len : copylen;
+
+ if (msg->msg_name != NULL)
+ memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn));
+
+out:
+ skb_free_datagram(sk, skb);
+
+out_nofree:
+ return rval;
+}
+
+/* Queue an skb for a sock. */
+static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb)
+{
+ int err = sock_queue_rcv_skb(sk, skb);
+ if (err < 0)
+ kfree_skb(skb);
+ return err;
+}
+
+/* Module registration */
+static struct proto pn_proto = {
+ .close = pn_sock_close,
+ .ioctl = pn_ioctl,
+ .init = pn_init,
+ .sendmsg = pn_sendmsg,
+ .recvmsg = pn_recvmsg,
+ .backlog_rcv = pn_backlog_rcv,
+ .hash = pn_sock_hash,
+ .unhash = pn_sock_unhash,
+ .get_port = pn_sock_get_port,
+ .obj_size = sizeof(struct pn_sock),
+ .owner = THIS_MODULE,
+ .name = "PHONET",
+};
+
+static struct phonet_protocol pn_dgram_proto = {
+ .ops = &phonet_dgram_ops,
+ .prot = &pn_proto,
+ .sock_type = SOCK_DGRAM,
+};
+
+int __init isi_register(void)
+{
+ return phonet_proto_register(PN_PROTO_PHONET, &pn_dgram_proto);
+}
+
+void __exit isi_unregister(void)
+{
+ phonet_proto_unregister(PN_PROTO_PHONET, &pn_dgram_proto);
+}
--
1.5.4.3
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 11/14] Phonet: provide MAC header operations
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (9 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 10/14] Phonet: Phonet datagram transport protocol Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 12/14] Phonet: proc interface for port range Rémi Denis-Courmont
` (4 subsequent siblings)
15 siblings, 0 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 12/14] Phonet: proc interface for port range
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (10 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 11/14] Phonet: provide MAC header operations Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 13/14] Phonet: emit errors when a packet cannot be delivered locally Rémi Denis-Courmont
` (3 subsequent siblings)
15 siblings, 0 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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();
phonet_netlink_register();
err = isi_register();
@@ -375,6 +376,7 @@ static int __init phonet_init(void)
return 0;
err2:
+ phonet_sysctl_exit();
phonet_device_exit();
unregister:
sock_unregister(AF_PHONET);
@@ -384,6 +386,7 @@ unregister:
static void __exit phonet_exit(void)
{
isi_unregister();
+ phonet_sysctl_exit();
sock_unregister(AF_PHONET);
dev_remove_pack(&phonet_packet_type);
phonet_device_exit();
diff --git a/net/phonet/socket.c b/net/phonet/socket.c
index 0e28327..ba2a975 100644
--- a/net/phonet/socket.c
+++ b/net/phonet/socket.c
@@ -268,8 +268,9 @@ int pn_sock_get_port(struct sock *sk, unsigned short sport)
if (!sport) {
/* search free port */
- int port, pmin = 0x40, pmax = 0x7f;
+ int port, pmin, pmax;
+ phonet_get_local_port_range(&pmin, &pmax);
for (port = pmin; port <= pmax; port++) {
port_cur++;
if (port_cur < pmin || port_cur > pmax)
diff --git a/net/phonet/sysctl.c b/net/phonet/sysctl.c
new file mode 100644
index 0000000..600a430
--- /dev/null
+++ b/net/phonet/sysctl.c
@@ -0,0 +1,113 @@
+/*
+ * File: sysctl.c
+ *
+ * Phonet /proc/sys/net/phonet interface implementation
+ *
+ * Copyright (C) 2008 Nokia Corporation.
+ *
+ * Contact: Remi 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/seqlock.h>
+#include <linux/sysctl.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+
+#define DYNAMIC_PORT_MIN 0x40
+#define DYNAMIC_PORT_MAX 0x7f
+
+static DEFINE_SEQLOCK(local_port_range_lock);
+static int local_port_range_min[2] = {0, 0};
+static int local_port_range_max[2] = {1023, 1023};
+static int local_port_range[2] = {DYNAMIC_PORT_MIN, DYNAMIC_PORT_MAX};
+static struct ctl_table_header *phonet_table_hrd;
+
+static void set_local_port_range(int range[2])
+{
+ write_seqlock(&local_port_range_lock);
+ local_port_range[0] = range[0];
+ local_port_range[1] = range[1];
+ write_sequnlock(&local_port_range_lock);
+}
+
+void phonet_get_local_port_range(int *min, int *max)
+{
+ unsigned seq;
+ do {
+ seq = read_seqbegin(&local_port_range_lock);
+ if (min)
+ *min = local_port_range[0];
+ if (max)
+ *max = local_port_range[1];
+ } while (read_seqretry(&local_port_range_lock, seq));
+}
+
+static int proc_local_port_range(ctl_table *table, int write, struct file *filp,
+ void __user *buffer,
+ size_t *lenp, loff_t *ppos)
+{
+ int ret;
+ int range[2] = {local_port_range[0], local_port_range[1]};
+ ctl_table tmp = {
+ .data = &range,
+ .maxlen = sizeof(range),
+ .mode = table->mode,
+ .extra1 = &local_port_range_min,
+ .extra2 = &local_port_range_max,
+ };
+
+ ret = proc_dointvec_minmax(&tmp, write, filp, buffer, lenp, ppos);
+
+ if (write && ret == 0) {
+ if (range[1] < range[0])
+ ret = -EINVAL;
+ else
+ set_local_port_range(range);
+ }
+
+ return ret;
+}
+
+static struct ctl_table phonet_table[] = {
+ {
+ .ctl_name = CTL_UNNUMBERED,
+ .procname = "local_port_range",
+ .data = &local_port_range,
+ .maxlen = sizeof(local_port_range),
+ .mode = 0644,
+ .proc_handler = &proc_local_port_range,
+ .strategy = NULL,
+ },
+ { .ctl_name = 0 }
+};
+
+struct ctl_path phonet_ctl_path[] = {
+ { .procname = "net", .ctl_name = CTL_NET, },
+ { .procname = "phonet", .ctl_name = CTL_UNNUMBERED, },
+ { },
+};
+
+int __init phonet_sysctl_init(void)
+{
+ phonet_table_hrd = register_sysctl_paths(phonet_ctl_path, phonet_table);
+ return phonet_table_hrd == NULL ? -ENOMEM : 0;
+}
+
+void phonet_sysctl_exit(void)
+{
+ unregister_sysctl_table(phonet_table_hrd);
+}
--
1.5.4.3
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 13/14] Phonet: emit errors when a packet cannot be delivered locally
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (11 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 12/14] Phonet: proc interface for port range Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 17:11 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 14/14] Phonet: kernel documentation Rémi Denis-Courmont
` (2 subsequent siblings)
15 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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 *skb)
+{
+ const struct phonethdr *ph = pn_hdr(skb);
+ struct phonet_device *pnd;
+
+ if (!pskb_may_pull(skb, 3))
+ return 0;
+ if (skb->data[1] == 0xF0)
+ return 0;
+ if (skb->data[2] == 0x01 || skb->data[2] == 0x14)
+ return 0;
+
+ spin_lock(&pndevs.lock);
+ pnd = __phonet_get_by_index(skb->dev->ifindex);
+ if (!pnd
+ || !phonet_dev2addr(pnd, ph->rdev & 0xFC, PN_FIND_EXACT)) {
+ spin_unlock(&pndevs.lock);
+ return 0;
+ }
+ spin_unlock(&pndevs.lock);
+ return 1;
+}
+
+static int send_obj_unreachable(struct sk_buff *rskb)
+{
+ struct phonethdr *oph = pn_hdr(rskb);
+ uint8_t data[8];
+
+ BUG_ON(skb_headlen(rskb) < 2);
+ data[0] = rskb->data[0];
+ data[1] = 0xF0;
+ data[2] = 0x14;
+ data[3] = rskb->data[1];
+ data[4] = 0x00;
+ data[5] = 0x00;
+ data[6] = 0x00;
+ data[7] = 0x00;
+ return pn_raw_send(data, sizeof(data), rskb->dev,
+ pn_object(oph->sdev, oph->sobj),
+ pn_object(oph->rdev, oph->robj),
+ oph->function);
+}
+
+static int send_reset_indications(struct sk_buff *rskb)
+{
+ struct phonethdr *oph = pn_hdr(rskb);
+ uint8_t data[4] = { 0x00, 0x10, 0x00, 0x00 };
+
+ return pn_raw_send(data, sizeof(data), rskb->dev,
+ pn_object(oph->sdev, 0x00),
+ pn_object(oph->rdev, oph->robj), 0x10);
+}
+
+
/* packet type functions */
/*
@@ -269,8 +338,13 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
goto out; /* currently, we cannot be device 0 */
sk = pn_find_sock_by_sa(&sa);
- if (sk == NULL)
+ if (sk == NULL) {
+ if (can_respond(skb)) {
+ send_obj_unreachable(skb);
+ send_reset_indications(skb);
+ }
goto out;
+ }
/* Push data to the socket (or other sockets connected to it). */
err = pn_sk(sk)->handler(sk, skb);
--
1.5.4.3
^ permalink raw reply related [flat|nested] 41+ messages in thread
* [PATCH 14/14] Phonet: kernel documentation
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (12 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 13/14] Phonet: emit errors when a packet cannot be delivered locally Rémi Denis-Courmont
@ 2008-09-16 15:08 ` Rémi Denis-Courmont
2008-09-16 20:09 ` [PATCH 00/14] [RFC] Phonet protocol stack Marcel Holtmann
2008-09-17 4:15 ` Dan Williams
15 siblings, 0 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-16 15:08 UTC (permalink / raw)
To: netdev
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 address number zero. Each other device has a its
+own 6-bits address.
+
+
+Link layer
+----------
+
+Phonet links are always point-to-point links. The link layer header
+consists of a single Phonet media type byte. It uniquely identifies the
+link through which the packet is transmitted, from the modem's
+perspective.
+
+Linux Phonet network interfaces use a dedicated link layer type
+(ETH_P_PHONET) which is out of the Ethernet type range. They can only
+send and receive Phonet packets.
+
+Note that Phonet interfaces are not allowed to re-order packets, so
+only the (default) Linux FIFO qdisc should be used with them.
+
+
+Network layer
+-------------
+
+The Phonet socket address family maps the Phonet packet header:
+
+ struct sockaddr_pn {
+ sa_family_t spn_family; /* AF_PHONET */
+ uint8_t spn_obj; /* Object ID */
+ uint8_t spn_dev; /* Device ID */
+ uint8_t spn_resource; /* Resource or function */
+ uint8_t spn_zero[...]; /* Padding */
+ };
+
+The resource field is only used when sending and receiving;
+It is ignored by bind() and getsockname().
+
+
+Low-level datagram protocol
+---------------------------
+
+Applications can send Phonet messages using the Phonet datagram socket
+protocol from the PF_PHONET family. Each socket is bound to one of the
+2^10 object IDs available, and can send and receive packets with any
+other peer.
+
+ struct sockaddr_pn addr = { .spn_family = AF_PHONET, };
+ ssize_t len;
+ socklen_t addrlen = sizeof(addr);
+ int fd;
+
+ fd = socket(PF_PHONET, SOCK_DGRAM, 0);
+ bind(fd, (struct sockaddr *)&addr, sizeof(addr));
+ /* ... */
+
+ sendto(fd, msg, msglen, 0, (struct sockaddr *)&addr, sizeof(addr));
+ len = recvfrom(fd, buf, sizeof(buf), 0,
+ (struct sockaddr *)&addr, &addrlen);
+
+This protocol follows the SOCK_DGRAM connection-less semantics.
+However, connect() and getpeername() are not supported, as they did
+not seem useful with Phonet usages (could be added easily).
+
+
+Authors
+-------
+
+Linux Phonet was initially written by Sakari Ailus.
+Other contributors include Mikä Liljeberg, Andras Domokos,
+Carlos Chinea and Rémi Denis-Courmont.
+Copyright (C) 2008 Nokia Corporation.
--
1.5.4.3
^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH 02/14] Phonet: add CONFIG_PHONET
2008-09-16 15:08 ` [PATCH 02/14] Phonet: add CONFIG_PHONET Rémi Denis-Courmont
@ 2008-09-16 16:06 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-09-16 16:06 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Em Tue, Sep 16, 2008 at 06:08:02PM +0300, Rémi Denis-Courmont escreveu:
> 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.
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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 03/14] Phonet: build the net/phonet/ directory
2008-09-16 15:08 ` [PATCH 03/14] Phonet: build the net/phonet/ directory Rémi Denis-Courmont
@ 2008-09-16 16:06 ` Arnaldo Carvalho de Melo
2008-09-17 4:52 ` Simon Horman
0 siblings, 1 reply; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-09-16 16:06 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Em Tue, Sep 16, 2008 at 06:08:03PM +0300, Rémi Denis-Courmont escreveu:
> Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
> ---
> net/Kconfig | 1 +
> net/Makefile | 1 +
> 2 files changed, 2 insertions(+), 0 deletions(-)
Can't this be combined with 2/14?
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 04/14] Phonet: PF_PHONET protocol family support
2008-09-16 15:08 ` [PATCH 04/14] Phonet: PF_PHONET protocol family support Rémi Denis-Courmont
@ 2008-09-16 16:17 ` Arnaldo Carvalho de Melo
2008-09-17 10:48 ` Rémi Denis-Courmont
0 siblings, 1 reply; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-09-16 16:17 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Em Tue, Sep 16, 2008 at 06:08:04PM +0300, Rémi Denis-Courmont escreveu:
> 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 = pn_object(ph->sdev, ph->sobj);
> +
> + sa->spn_family = AF_PHONET;
> + pn_sockaddr_set_object(sa, obj);
> + pn_sockaddr_set_resource(sa, ph->function);
> + memset(sa->spn_zero, 0, sizeof(sa->spn_zero));
> +}
> +
> +static inline
> +void pn_skb_get_dst_sockaddr(struct sk_buff *skb, struct sockaddr_pn *sa)
> +{
> + struct phonethdr *ph = pn_hdr(skb);
> + uint16_t obj = pn_object(ph->rdev, ph->robj);
> +
> + sa->spn_family = AF_PHONET;
> + pn_sockaddr_set_object(sa, obj);
> + pn_sockaddr_set_resource(sa, ph->function);
> + memset(sa->spn_zero, 0, sizeof(sa->spn_zero));
> +}
> +
> +/* Protocols in Phonet protocol family. */
> +struct phonet_protocol {
> + struct proto *prot;
> + int sock_type;
> +};
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?
Lemme continue, perhaps phonet_proto_register can tell me...
> +int phonet_proto_register(int protocol, struct phonet_protocol *pp);
> +void phonet_proto_unregister(int protocol, struct phonet_protocol *pp);
> +
> +#endif
> diff --git a/net/phonet/Makefile b/net/phonet/Makefile
> index 4ced746..5dbff68 100644
> --- a/net/phonet/Makefile
> +++ b/net/phonet/Makefile
> @@ -1,3 +1,4 @@
> obj-$(CONFIG_PHONET) += phonet.o
>
> -phonet-objs :=
> +phonet-objs := \
> + af_phonet.o
> diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
> new file mode 100644
> index 0000000..ed66a81
> --- /dev/null
> +++ b/net/phonet/af_phonet.c
> @@ -0,0 +1,218 @@
> +/*
> + * File: af_phonet.c
> + *
> + * Phonet protocols family
> + *
> + * 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 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/module.h>
> +#include <asm/unaligned.h>
> +#include <net/sock.h>
> +
> +#include <linux/if_phonet.h>
> +#include <linux/phonet.h>
> +#include <net/phonet/phonet.h>
> +
> +static struct net_proto_family phonet_proto_family;
> +static struct phonet_protocol *phonet_proto_get(int protocol);
> +static inline void phonet_proto_put(struct phonet_protocol *pp);
> +
> +/* protocol family functions */
> +
> +static int pn_socket_create(struct net *net, struct socket *sock, int protocol)
> +{
> + struct phonet_protocol *pnp;
> + int err;
> +
> + if (net != &init_net)
> + return -EAFNOSUPPORT;
> +
> + if (!capable(CAP_SYS_ADMIN))
> + return -EPERM;
> +
> + if (protocol == 0) {
> + /* Default protocol selection */
> + switch (sock->type) {
> + case SOCK_RDM:
> + case SOCK_DGRAM:
> + protocol = PN_PROTO_PHONET;
> + break;
Here, the mapping, and we even have struct socket sock->type in addition
to struct sock->sk_type
> + default:
> + return -EPROTONOSUPPORT;
> + }
> + }
> +
> + pnp = phonet_proto_get(protocol);
> + if (pnp == NULL)
> + return -EPROTONOSUPPORT;
> + if (sock->type != pnp->sock_type &&
> + (protocol != PN_PROTO_PHONET || sock->type != SOCK_RDM)) {
> + err = -EPROTONOSUPPORT;
> + goto out;
> + }
> +
> + /* TODO: create and init the struct sock */
I see, you're ot using struct sock at all :-)
> + err = -EPROTONOSUPPORT;
> +
> +out:
> + phonet_proto_put(pnp);
> + return err;
> +}
> +
> +static struct net_proto_family phonet_proto_family = {
> + .family = AF_PHONET,
> + .create = pn_socket_create,
> + .owner = THIS_MODULE,
> +};
> +
> +/* packet type functions */
> +
> +/*
> + * Stuff received packets to associated sockets.
> + * On error, returns non-zero and releases the skb.
> + */
> +static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
> + struct packet_type *pkttype,
> + struct net_device *orig_dev)
> +{
> + struct phonethdr *ph;
> + struct sockaddr_pn sa;
> + u16 len;
> +
> + if (dev_net(dev) != &init_net)
> + goto out;
> +
> + /* check we have at least a full Phonet header */
> + if (!pskb_pull(skb, sizeof(struct phonethdr)))
> + goto out;
> +
> + /* check that the advertised length is correct */
> + ph = pn_hdr(skb);
> + len = get_unaligned_be16(&ph->length);
> + if (len < 2)
> + goto out;
> + len -= 2;
> + if ((len > skb->len) || pskb_trim(skb, len))
> + goto out;
> + skb_reset_transport_header(skb);
> +
> + pn_skb_get_dst_sockaddr(skb, &sa);
> + if (pn_sockaddr_get_addr(&sa) == 0)
> + goto out; /* currently, we cannot be device 0 */
> +
> + /* TODO: put packets to sockets backlog */
I guess this will be done in the next patches, interesting way of
breaking up the patches...
> +out:
> + kfree_skb(skb);
> + return NET_RX_DROP;
> +}
> +
> +static struct packet_type phonet_packet_type = {
> + .type = __constant_htons(ETH_P_PHONET),
> + .dev = NULL,
> + .func = phonet_rcv,
> +};
> +
> +/* Transport protocol registration */
> +static struct phonet_protocol *proto_tab[PHONET_NPROTO] __read_mostly;
> +static DEFINE_SPINLOCK(proto_tab_lock);
> +
> +int __init_or_module phonet_proto_register(int protocol,
> + struct phonet_protocol *pp)
> +{
> + int err = 0;
> +
> + if (protocol >= PHONET_NPROTO)
> + return -EINVAL;
> +
> + err = proto_register(pp->prot, 1);
Cool, it uses proto_register :-)
> + if (err)
> + return err;
> +
> + spin_lock(&proto_tab_lock);
> + if (proto_tab[protocol])
> + err = -EBUSY;
> + else
> + proto_tab[protocol] = pp;
> + spin_unlock(&proto_tab_lock);
> +
> + return err;
> +}
> +EXPORT_SYMBOL(phonet_proto_register);
> +
> +void phonet_proto_unregister(int protocol, struct phonet_protocol *pp)
> +{
> + spin_lock(&proto_tab_lock);
> + BUG_ON(proto_tab[protocol] != pp);
> + proto_tab[protocol] = NULL;
> + spin_unlock(&proto_tab_lock);
> + proto_unregister(pp->prot);
> +}
> +EXPORT_SYMBOL(phonet_proto_unregister);
> +
> +static struct phonet_protocol *phonet_proto_get(int protocol)
> +{
> + struct phonet_protocol *pp;
> +
> + if (protocol >= PHONET_NPROTO)
> + return NULL;
> +
> + spin_lock(&proto_tab_lock);
> + pp = proto_tab[protocol];
> + if (pp && !try_module_get(pp->prot->owner))
> + pp = NULL;
> + spin_unlock(&proto_tab_lock);
> +
> + return pp;
> +}
> +
> +static inline void phonet_proto_put(struct phonet_protocol *pp)
> +{
> + module_put(pp->prot->owner);
> +}
> +
> +/* Module registration */
> +static int __init phonet_init(void)
> +{
> + int err;
> +
> + err = sock_register(&phonet_proto_family);
> + if (err) {
> + printk(KERN_ALERT
> + "phonet protocol family initialization failed\n");
> + return err;
> + }
> +
> + dev_add_pack(&phonet_packet_type);
> + return 0;
> +}
> +
> +static void __exit phonet_exit(void)
> +{
> + sock_unregister(AF_PHONET);
> + dev_remove_pack(&phonet_packet_type);
> +}
> +
> +module_init(phonet_init);
> +module_exit(phonet_exit);
> +MODULE_DESCRIPTION("Phonet protocol stack for Linux");
> +MODULE_LICENSE("GPL");
> --
> 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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 05/14] Phonet: network device and address handling
2008-09-16 15:08 ` [PATCH 05/14] Phonet: network device and address handling Rémi Denis-Courmont
@ 2008-09-16 16:41 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-09-16 16:41 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Em Tue, Sep 16, 2008 at 06:08:05PM +0300, Rémi Denis-Courmont escreveu:
> 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 *phonet_device_alloc(struct net_device *dev);
> +struct phonet_device *__phonet_get_by_index(unsigned ifindex);
> +void phonet_device_free(struct phonet_device *pnd);
> +
> +struct phonet_address *phonet_address_alloc(void);
> +void phonet_address_add(struct list_head *list, struct phonet_address *pna);
> +void phonet_address_free(struct phonet_address *pna);
> +struct phonet_address *phonet_addr2addr(uint8_t addr, int mode);
> +struct phonet_address *phonet_dev2addr(struct phonet_device *pnd, uint8_t addr,
> + int mode);
> +
> +#define PN_FIND_EXACT (1 << 0)
> +
> +#define MKMASK(a) ((1 << (a)) - 1)
> +
> +#endif
> diff --git a/net/phonet/Makefile b/net/phonet/Makefile
> index 5dbff68..980a386 100644
> --- a/net/phonet/Makefile
> +++ b/net/phonet/Makefile
> @@ -1,4 +1,5 @@
> obj-$(CONFIG_PHONET) += phonet.o
>
> phonet-objs := \
> + pn_dev.o \
> af_phonet.o
> diff --git a/net/phonet/af_phonet.c b/net/phonet/af_phonet.c
> index ed66a81..744b47f 100644
> --- a/net/phonet/af_phonet.c
> +++ b/net/phonet/af_phonet.c
> @@ -31,6 +31,7 @@
> #include <linux/if_phonet.h>
> #include <linux/phonet.h>
> #include <net/phonet/phonet.h>
> +#include <net/phonet/pn_dev.h>
>
> static struct net_proto_family phonet_proto_family;
> static struct phonet_protocol *phonet_proto_get(int protocol);
> @@ -202,14 +203,25 @@ static int __init phonet_init(void)
> return err;
> }
>
> + err = phonet_device_init();
> + if (err) {
> + printk(KERN_ALERT "phonet devices initialization failed\n");
> + goto unregister;
> + }
> +
> dev_add_pack(&phonet_packet_type);
> return 0;
> +
> +unregister:
> + sock_unregister(AF_PHONET);
> + return err;
> }
>
> static void __exit phonet_exit(void)
> {
> sock_unregister(AF_PHONET);
> dev_remove_pack(&phonet_packet_type);
> + phonet_device_exit();
> }
>
> module_init(phonet_init);
> diff --git a/net/phonet/pn_dev.c b/net/phonet/pn_dev.c
> new file mode 100644
> index 0000000..cae37a6
> --- /dev/null
> +++ b/net/phonet/pn_dev.c
> @@ -0,0 +1,233 @@
> +/*
> + * File: pn_dev.c
> + *
> + * Phonet network device
> + *
> + * 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 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/net.h>
> +#include <linux/netdevice.h>
> +#include <linux/phonet.h>
> +#include <net/sock.h>
> +#include <net/phonet/pn_dev.h>
> +
> +static int phonet_device_notify(struct notifier_block *self, unsigned long what,
> + void *dev);
> +
> +/* when accessing, remember to lock with spin_lock(&pndevs.lock); */
> +struct phonet_device_list pndevs;
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
time, again.
> +static struct notifier_block phonet_device_notifier = {
> + .notifier_call = &phonet_device_notify,
> + .priority = 0,
> +};
> +
> +/* initialise Phonet device list */
> +int phonet_device_init(void)
> +{
> + INIT_LIST_HEAD(&pndevs.list);
> + spin_lock_init(&pndevs.lock);
> + register_netdevice_notifier(&phonet_device_notifier);
> +
> + return 0;
> +}
> +
> +void phonet_device_exit(void)
> +{
> + struct list_head *ptr;
> +
> + rtnl_unregister_all(PF_PHONET);
> + rtnl_lock();
> + spin_lock_bh(&pndevs.lock);
> +
> + for (ptr = pndevs.list.next; ptr != &pndevs.list;
> + ptr = pndevs.list.next) {
Perhaps a phone_for_each_dev() macro like for_each_netdev() in
linux/netdevice.h?
> + struct phonet_device *pnd = list_entry(ptr,
> + struct phonet_device, list);
> + phonet_device_free(pnd);
> + }
> +
> + spin_unlock_bh(&pndevs.lock);
> + rtnl_unlock();
> + unregister_netdevice_notifier(&phonet_device_notifier);
> +}
> +
> +struct phonet_address *phonet_address_alloc(void)
> +{
> + struct phonet_address *pna;
> +
> + pna = kmalloc(sizeof(struct phonet_address), GFP_KERNEL);
> +
> + if (pna == NULL)
> + return NULL;
> +
> + INIT_LIST_HEAD(&pna->list);
minor nitpick:
if (pna != NULL)
INIT_LIST_HEAD(&pna->list);
shorter :)
> +
> + return pna;
> +}
> +
> +/* add Phonet address to list */
> +void phonet_address_add(struct list_head *list, struct phonet_address *pna)
> +{
> + list_add(&pna->list, list);
> +}
> +
> +/* remove Phonet address from list and free it */
> +void phonet_address_free(struct phonet_address *pna)
> +{
> + list_del(&pna->list);
> + kfree(pna);
> +}
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
address, confusing.
> +/* Allocate new Phonet device. */
> +struct phonet_device *phonet_device_alloc(struct net_device *dev)
> +{
> + struct phonet_device *pnd;
> +
> + pnd = kmalloc(sizeof(struct phonet_device), GFP_ATOMIC);
> +
> + if (pnd == NULL)
> + return NULL;
> +
> + INIT_LIST_HEAD(&pnd->own);
> + pnd->netdev = dev;
> + list_add(&pnd->list, &pndevs.list);
> + return pnd;
> +}
> +
> +struct phonet_device *__phonet_get_by_index(unsigned ifindex)
> +{
> + struct list_head *p;
> +
> + list_for_each(p, &pndevs.list) {
> + struct phonet_device *pnd;
> +
> + pnd = list_entry(p, struct phonet_device, list);
> + BUG_ON(!pnd->netdev);
> +
> + if (pnd->netdev->ifindex == ifindex)
> + return pnd;
> + }
> + return NULL;
> +}
> +
> +void phonet_device_free(struct phonet_device *pnd)
> +{
> + struct list_head *ptr;
> +
> + /* remove device from list */
> + list_del(&pnd->list);
> +
> + for (ptr = pnd->own.next; ptr != &pnd->own; ptr = pnd->own.next) {
> + struct phonet_address *pna =
> + list_entry(ptr, struct phonet_address, list);
> + phonet_address_free(pna);
Why not use list_for_each_entry()? _safe() even, since
phonet_address_free also messes with this list, no?
> + }
> +
> + kfree(pnd);
> +}
> +
> +/*
> + * Find the address from the device's address list having the given address
> + */
> +struct phonet_address *phonet_dev2addr(struct phonet_device *pnd,
> + uint8_t addr, int mode)
> +{
> + struct list_head *list = &pnd->own, *ptr;
> + struct phonet_address *best = NULL;
> +
> + for (ptr = list->next; ptr != list; ptr = ptr->next) {
> + struct phonet_address *pna =
> + list_entry(ptr, struct phonet_address, list);
list_for_each_entry()
> + if (mode & PN_FIND_EXACT) {
> + /* try to find exact address */
> + if (pna->addr == addr) {
> + best = pna;
> + break;
> + }
> + } else if (best == NULL ||
> + best->prefix < pna->prefix) {
> + if ((pna->addr & MKMASK(pna->prefix)) ==
> + (addr & MKMASK(pna->prefix))) {
> + best = pna;
> + }
> + }
> + }
> +
> + return best;
> +}
> +
> +/*
> + * Find the device having a given address (remember locking!!)
> + */
> +struct phonet_address *phonet_addr2addr(uint8_t addr, int mode)
> +{
> + struct list_head *ptr;
> + struct phonet_address *best = NULL;
> +
> + for (ptr = pndevs.list.next; ptr != &pndevs.list; ptr = ptr->next) {
> + struct phonet_address *pna = NULL;
> + struct phonet_device *pnd =
> + list_entry(ptr, struct phonet_device, list);
Ditto
> +
> + /* Don't allow unregistering devices! */
> + if ((pnd->netdev->reg_state != NETREG_REGISTERED) ||
> + ((pnd->netdev->flags & IFF_UP)) != IFF_UP)
> + continue;
> +
> + pna = phonet_dev2addr(pnd, addr, mode);
> +
> + if (pna != NULL) {
> + if (best == NULL || best->prefix < pna->prefix)
> + best = pna;
> + }
> + }
> +
> + return best;
> +}
> +
> +/* notify Phonet of device events */
> +static int phonet_device_notify(struct notifier_block *self, unsigned long what,
> + void *_dev)
> +{
> + struct net_device *dev = _dev;
> + struct phonet_device *pnd;
> +
> + spin_lock_bh(&pndevs.lock);
> + pnd = __phonet_get_by_index(dev->ifindex);
> +
> + switch (what) {
> + case NETDEV_UNREGISTER:
> + if (pnd == NULL)
> + break;
> + phonet_device_free(pnd);
> + break;
> + default:
> + break;
> + }
if (what == NETDEV_UNREGISTER && pnd != NULL)
phonet_device_free(pnd);
Shorter, no? :)
> +
> + spin_unlock_bh(&pndevs.lock);
> +
> + return 0;
> +
> +}
> --
> 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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 07/14] Phonet: common socket glue
2008-09-16 15:08 ` [PATCH 07/14] Phonet: common socket glue Rémi Denis-Courmont
@ 2008-09-16 16:50 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-09-16 16:50 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Em Tue, Sep 16, 2008 at 06:08:07PM +0300, Rémi Denis-Courmont escreveu:
> 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))
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
as your pn_sock :)
> +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))
At least here skb_network_header() will do the typechecking for you.
> /*
> @@ -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 +3,5 @@ obj-$(CONFIG_PHONET) += phonet.o
> phonet-objs := \
> pn_dev.o \
> pn_netlink.o \
> + socket.o \
> af_phonet.o
> diff --git a/net/phonet/socket.c b/net/phonet/socket.c
> new file mode 100644
> index 0000000..0e28327
> --- /dev/null
> +++ b/net/phonet/socket.c
> @@ -0,0 +1,312 @@
> +/*
> + * File: socket.c
> + *
> + * Phonet sockets
> + *
> + * 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 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/net.h>
> +#include <net/sock.h>
> +#include <net/tcp_states.h>
> +
> +#include <linux/phonet.h>
> +#include <net/phonet/phonet.h>
> +#include <net/phonet/pn_dev.h>
> +
> +static int pn_socket_release(struct socket *sock)
> +{
> + struct sock *sk = sock->sk;
> +
> + if (sk) {
> + sock->sk = NULL;
> + sk->sk_prot->close(sk, 0);
> + }
> + return 0;
> +}
> +
> +static struct {
> + struct hlist_head hlist;
> + spinlock_t lock;
> +} pnsocks;
See tcp_death_row on how to initialize it right here and not at some
init function.
> +/*
> + * Find address based on socket address, match only certain fields.
> + * Also grab sock if it was found. Remember to sock_put it later.
> + */
> +struct sock *pn_find_sock_by_sa(const struct sockaddr_pn *spn)
> +{
> + struct hlist_node *node;
> + struct sock *sknode;
> + struct sock *rval = NULL;
> + uint16_t obj = pn_sockaddr_get_object(spn);
> + uint8_t res = spn->spn_resource;
> +
> + spin_lock_bh(&pnsocks.lock);
> +
> + sk_for_each(sknode, node, &pnsocks.hlist) {
> + struct pn_sock *pn = pn_sk(sknode);
> + BUG_ON(!pn->sobject); /* unbound socket */
> +
> + if (pn_port(obj)) {
> + /* Look up socket by port */
> + if (pn_port(pn->sobject) != pn_port(obj))
> + continue;
> + } else {
> + /* If port is zero, look up by resource */
> + if (pn->resource != res)
> + continue;
> + }
> + if (pn_addr(pn->sobject)
> + && pn_addr(pn->sobject) != pn_addr(obj))
Please && at the end of previous line
> + continue;
> +
> + rval = sknode;
> + sock_hold(sknode);
> + break;
> + }
> +
> + spin_unlock_bh(&pnsocks.lock);
> +
> + return rval;
> +
> +}
> +
> +void pn_sock_hash(struct sock *sk)
> +{
> + spin_lock_bh(&pnsocks.lock);
> + sk_add_node(sk, &pnsocks.hlist);
> + spin_unlock_bh(&pnsocks.lock);
> +}
> +EXPORT_SYMBOL(pn_sock_hash);
> +
> +void pn_sock_unhash(struct sock *sk)
> +{
> + spin_lock_bh(&pnsocks.lock);
> + sk_del_node_init(sk);
> + spin_unlock_bh(&pnsocks.lock);
> +}
> +EXPORT_SYMBOL(pn_sock_unhash);
> +
> +static int pn_socket_bind(struct socket *sock, struct sockaddr *addr, int len)
> +{
> + struct sock *sk = sock->sk;
> + struct pn_sock *pn = pn_sk(sk);
> + struct sockaddr_pn *spn = (struct sockaddr_pn *)addr;
> + int err;
> + uint16_t handle;
> + uint8_t saddr;
> +
> + if (sk->sk_prot->bind)
> + return sk->sk_prot->bind(sk, addr, len);
> +
> + if (len < sizeof(struct sockaddr_pn))
> + return -EINVAL;
> + if (spn->spn_family != AF_PHONET)
> + return -EAFNOSUPPORT;
> +
> + handle = pn_sockaddr_get_object((struct sockaddr_pn *)addr);
> + saddr = pn_addr(handle);
> + if (saddr) {
> + struct phonet_address *pna;
> +
> + spin_lock_bh(&pndevs.lock);
> + pna = phonet_addr2addr(pn_addr(handle), PN_FIND_EXACT);
> + spin_unlock_bh(&pndevs.lock);
> + if (pna == NULL)
> + return -EADDRNOTAVAIL;
> + }
> +
> + lock_sock(sk);
> + if (sk->sk_state != TCP_CLOSE || pn_port(pn->sobject)) {
> + err = -EINVAL; /* attempt to rebind */
> + goto out;
> + }
> + err = sk->sk_prot->get_port(sk, pn_port(handle));
> + if (err)
> + goto out;
> +
> + /* get_port() sets the port, bind() sets the address if applicable */
> + pn->sobject = pn_object(saddr, pn_port(pn->sobject));
> + pn->resource = spn->spn_resource;
> +
> + /* Enable RX on the socket */
> + sk->sk_prot->hash(sk);
> +out:
> + release_sock(sk);
> + return err;
> +}
> +
> +static int pn_socket_autobind(struct socket *sock)
> +{
> + struct sockaddr_pn sa;
> + int err;
> +
> + memset(&sa, 0, sizeof(sa));
> + sa.spn_family = AF_PHONET;
> + err = pn_socket_bind(sock, (struct sockaddr *)&sa,
> + sizeof(struct sockaddr_pn));
> + if (err != -EINVAL)
> + return err;
> + BUG_ON(!pn_port(pn_sk(sock->sk)->sobject));
> + return 0; /* socket was already bound */
> +}
> +
> +static int pn_socket_getname(struct socket *sock, struct sockaddr *addr,
> + int *sockaddr_len, int peer)
> +{
> + struct sock *sk = sock->sk;
> + struct pn_sock *pn = pn_sk(sk);
> +
> + memset(addr, 0, sizeof(struct sockaddr_pn));
> + addr->sa_family = AF_PHONET;
> + if (!peer) /* Race with bind() here is userland's problem. */
> + pn_sockaddr_set_object((struct sockaddr_pn *)addr,
> + pn->sobject);
> +
> + *sockaddr_len = sizeof(struct sockaddr_pn);
> + return 0;
> +}
> +
> +static int pn_socket_ioctl(struct socket *sock, unsigned int cmd,
> + unsigned long arg)
> +{
> + struct sock *sk = sock->sk;
> + struct pn_sock *pn = pn_sk(sk);
> +
> + if (cmd == SIOCPNGETOBJECT) {
> + struct phonet_address *pna;
> + uint16_t handle;
> + uint8_t rdev;
> +
> + if (get_user(handle, (uint16_t __user *)arg))
> + return -EFAULT;
> +
> + rdev = pn_dev(handle);
> + spin_lock_bh(&pndevs.lock);
> + pna = phonet_addr2addr(rdev, 0);
> + if (pna)
> + handle = pn_object(pna->addr, pn_port(pn->sobject));
> + spin_unlock_bh(&pndevs.lock);
> +
> + if (!pna)
> + return -EHOSTUNREACH;
> + return put_user(handle, (uint16_t __user *)arg);
> + }
> +
> + return sk->sk_prot->ioctl(sk, cmd, arg);
I guess it is a requirement that each protocol will provide an ioctl
handler.
> +}
> +
> +static int pn_socket_sendmsg(struct kiocb *iocb, struct socket *sock,
> + struct msghdr *m, size_t total_len)
> +{
> + struct sock *sk = sock->sk;
> +
> + if (pn_socket_autobind(sock))
> + return -EAGAIN;
> +
> + return sk->sk_prot->sendmsg(iocb, sk, m, total_len);
> +}
> +
> +const struct proto_ops phonet_dgram_ops = {
> + .family = AF_PHONET,
> + .owner = THIS_MODULE,
> + .release = pn_socket_release,
> + .bind = pn_socket_bind,
> + .connect = sock_no_connect,
> + .socketpair = sock_no_socketpair,
> + .accept = sock_no_accept,
> + .getname = pn_socket_getname,
> + .poll = datagram_poll,
> + .ioctl = pn_socket_ioctl,
> + .listen = sock_no_listen,
> + .shutdown = sock_no_shutdown,
> + .setsockopt = sock_no_setsockopt,
> + .getsockopt = sock_no_getsockopt,
> +#ifdef CONFIG_COMPAT
> + .compat_setsockopt = sock_no_setsockopt,
> + .compat_getsockopt = sock_no_getsockopt,
> +#endif
> + .sendmsg = pn_socket_sendmsg,
> + .recvmsg = sock_common_recvmsg,
> + .mmap = sock_no_mmap,
> + .sendpage = sock_no_sendpage,
> +};
> +
> +static DEFINE_MUTEX(port_mutex);
> +
> +/* allocate port for a socket */
> +int pn_sock_get_port(struct sock *sk, unsigned short sport)
> +{
> + static int port_cur;
> + struct pn_sock *pn = pn_sk(sk);
> + struct sockaddr_pn try_sa;
> + struct sock *tmpsk;
> +
> + memset(&try_sa, 0, sizeof(struct sockaddr_pn));
> + try_sa.spn_family = AF_PHONET;
> +
> + mutex_lock(&port_mutex);
> +
> + if (!sport) {
> + /* search free port */
> + int port, pmin = 0x40, pmax = 0x7f;
> +
> + for (port = pmin; port <= pmax; port++) {
> + port_cur++;
> + if (port_cur < pmin || port_cur > pmax)
> + port_cur = pmin;
> +
> + pn_sockaddr_set_port(&try_sa, port_cur);
> + tmpsk = pn_find_sock_by_sa(&try_sa);
> + if (tmpsk == NULL) {
> + sport = port_cur;
> + goto found;
> + } else
> + sock_put(tmpsk);
> + }
> + } else {
> + /* try to find specific port */
> + pn_sockaddr_set_port(&try_sa, sport);
> + tmpsk = pn_find_sock_by_sa(&try_sa);
> + if (tmpsk == NULL)
> + /* No sock there! We can use that port... */
> + goto found;
> + else
> + sock_put(tmpsk);
> + }
> + mutex_unlock(&port_mutex);
> +
> + /* the port must be in use already */
> + return -EADDRINUSE;
> +
> +found:
> + mutex_unlock(&port_mutex);
> + pn->sobject = pn_object(pn_addr(pn->sobject), sport);
> + return 0;
> +}
> +EXPORT_SYMBOL(pn_sock_get_port);
> +
> +void __init phonet_socket_init(void)
> +{
> + INIT_HLIST_HEAD(&pnsocks.hlist);
> + spin_lock_init(&pnsocks.lock);
> +}
> --
> 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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 08/14] Phonet: receive path socket lookup
2008-09-16 15:08 ` [PATCH 08/14] Phonet: receive path socket lookup Rémi Denis-Courmont
@ 2008-09-16 16:52 ` Arnaldo Carvalho de Melo
2008-09-19 6:20 ` Rémi Denis-Courmont
0 siblings, 1 reply; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-09-16 16:52 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Em Tue, Sep 16, 2008 at 06:08:08PM +0300, Rémi Denis-Courmont escreveu:
> 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);
wouldn't be nice to use sk_backlog_rcv() and sk_receive_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
>
> --
> 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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 09/14] Phonet: allocate and initialize new sockets
2008-09-16 15:08 ` [PATCH 09/14] Phonet: allocate and initialize new sockets Rémi Denis-Courmont
@ 2008-09-16 16:53 ` Arnaldo Carvalho de Melo
2008-09-16 18:42 ` Pavel Emelyanov
1 sibling, 0 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-09-16 16:53 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Em Tue, Sep 16, 2008 at 06:08:09PM +0300, Rémi Denis-Courmont escreveu:
> 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;
Scrap the comment I made in a previous patch, I guess
> + 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
>
> --
> 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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 10/14] Phonet: Phonet datagram transport protocol
2008-09-16 15:08 ` [PATCH 10/14] Phonet: Phonet datagram transport protocol Rémi Denis-Courmont
@ 2008-09-16 17:06 ` Arnaldo Carvalho de Melo
2008-09-19 6:33 ` Rémi Denis-Courmont
0 siblings, 1 reply; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-09-16 17:06 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Em Tue, Sep 16, 2008 at 06:08:10PM +0300, Rémi Denis-Courmont escreveu:
> 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) {
wow, what a magic number! :-)
> + err = -EMSGSIZE;
> + goto drop;
> + }
> +
> + skb_reset_transport_header(skb);
> + WARN_ON(skb_headroom(skb) & 1); /* HW assumes word alignment */
> + ph = (struct phonethdr *)skb_push(skb, sizeof(struct phonethdr));
> + skb_reset_network_header(skb);
Here you could just use:
ph = (struct phonethdr *)skb_network_header(skb);
or even just:
ph = pn_hdr(skb);
as other protocols such as IP do (see ip_hdr())
> + ph->rdev = pn_dev(dst);
> + ph->sdev = pn_dev(src);
> + ph->function = res;
> + ph->length = __cpu_to_be16(skb->len + 2 - sizeof(*ph));
> + ph->robj = pn_obj(dst);
> + ph->sobj = pn_obj(src);
> +
> + skb->protocol = __constant_htons(ETH_P_PHONET);
No need for __constant_htons(CONSTANT), htons will do the right thing
and the code will be shorter, clearer.
> + skb->priority = 0;
> + skb->dev = dev;
> +
> + if (pn_addr(src) == pn_addr(dst)) {
> + skb_reset_mac_header(skb);
> + skb->pkt_type = PACKET_LOOPBACK;
> + skb_orphan(skb);
> + netif_rx_ni(skb);
> + err = 0;
> + } else {
> + err = dev_hard_header(skb, dev, ntohs(skb->protocol),
> + NULL, NULL, skb->len);
> + if (err < 0) {
> + err = -EHOSTUNREACH;
> + goto drop;
> + }
> + err = dev_queue_xmit(skb);
> + }
> +
> + return err;
> +drop:
> + kfree_skb(skb);
> + return err;
> +}
> +
> +/*
> + * Create a Phonet header for the skb and send it out. Returns
> + * non-zero error code if failed. The skb is freed then.
> + */
> +int pn_skb_send(struct sock *sk, struct sk_buff *skb,
> + const struct sockaddr_pn *target)
> +{
> + struct net_device *dev;
> + struct phonet_address *pna = NULL;
> + struct pn_sock *pn = pn_sk(sk);
> + int err;
> + uint16_t src;
> + uint8_t addr = pn_sockaddr_get_addr(target);
> +
> + spin_lock_bh(&pndevs.lock);
> + if (sk->sk_bound_dev_if) {
> + struct phonet_device *pnd;
> +
> + pnd = __phonet_get_by_index(sk->sk_bound_dev_if);
> + if (pnd && (pnd->netdev->flags & IFF_UP))
> + pna = phonet_dev2addr(pnd, addr, 0);
> + } else {
> + pna = phonet_addr2addr(pn_sockaddr_get_addr(target), 0);
> + }
> +
> + if (pna == NULL) {
> + spin_unlock_bh(&pndevs.lock);
> + err = -EHOSTUNREACH;
> + goto drop;
> + }
> +
> + src = pn->sobject;
> + if (!pn_addr(src))
> + src = pn_object(pna->addr, pn_obj(src));
> +
> + dev = pna->pnd->netdev;
> + dev_hold(dev);
> + spin_unlock_bh(&pndevs.lock);
> +
> + err = pn_send(skb, dev, pn_sockaddr_get_object(target),
> + src, pn_sockaddr_get_resource(target));
> + dev_put(dev);
> + return err;
> +
> +drop:
> + kfree_skb(skb);
> + return err;
> +}
> +EXPORT_SYMBOL(pn_skb_send);
> +
> /* packet type functions */
>
> /*
> @@ -238,8 +339,14 @@ static int __init phonet_init(void)
>
> dev_add_pack(&phonet_packet_type);
> phonet_netlink_register();
> +
> + err = isi_register();
> + if (err)
> + goto err2;
> return 0;
>
> +err2:
> + phonet_device_exit();
> unregister:
> sock_unregister(AF_PHONET);
> return err;
> @@ -247,6 +354,7 @@ unregister:
>
> static void __exit phonet_exit(void)
> {
> + isi_unregister();
> sock_unregister(AF_PHONET);
> dev_remove_pack(&phonet_packet_type);
> phonet_device_exit();
> diff --git a/net/phonet/datagram.c b/net/phonet/datagram.c
> new file mode 100644
> index 0000000..5d8e701
> --- /dev/null
> +++ b/net/phonet/datagram.c
> @@ -0,0 +1,198 @@
> +/*
> + * File: datagram.c
> + *
> + * Datagram (ISI) Phonet sockets
> + *
> + * 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 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/socket.h>
> +#include <asm/ioctls.h>
> +#include <net/sock.h>
> +
> +#include <linux/phonet.h>
> +#include <net/phonet/phonet.h>
> +
> +static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb);
> +
> +/* associated socket ceases to exist */
> +static void pn_sock_close(struct sock *sk, long timeout)
> +{
> + sk_common_release(sk);
> +}
> +
> +static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg)
> +{
> + struct sk_buff *skb;
> + int answ;
> +
> + switch (cmd) {
> + case SIOCINQ:
> + spin_lock_bh(&sk->sk_receive_queue.lock);
> + skb = skb_peek(&sk->sk_receive_queue);
> + answ = skb ? skb->len : 0;
> + spin_unlock_bh(&sk->sk_receive_queue.lock);
> + return put_user(answ, (int __user *)arg);
Why not use lock_sock/release_sock as tcp?
> + }
> +
> + return -ENOIOCTLCMD;
> +}
> +
> +/* Destroy socket. All references are gone. */
> +static void pn_destruct(struct sock *sk)
> +{
> + skb_queue_purge(&sk->sk_receive_queue);
> +}
> +
> +static int pn_init(struct sock *sk)
> +{
> + sk->sk_destruct = pn_destruct;
> + pn_sk(sk)->handler = pn_backlog_rcv;
Humm, why not use sk_receive_skb/ sk_backlog_rcv?
> + return 0;
> +}
> +
> +static int pn_sendmsg(struct kiocb *iocb, struct sock *sk,
> + struct msghdr *msg, size_t len)
> +{
> + struct sockaddr_pn *target;
> + struct sk_buff *skb;
> + int err;
> +
> + if (msg->msg_flags & MSG_OOB)
> + return -EOPNOTSUPP;
> +
> + if (msg->msg_name == NULL)
> + return -EDESTADDRREQ;
> +
> + if (msg->msg_namelen < sizeof(struct sockaddr_pn))
> + return -EINVAL;
> +
> + target = (struct sockaddr_pn *)msg->msg_name;
> + if (target->spn_family != AF_PHONET)
> + return -EAFNOSUPPORT;
> +
> + skb = sock_alloc_send_skb(sk, MAX_PHONET_HEADER + len,
> + msg->msg_flags & MSG_DONTWAIT, &err);
> + if (skb == NULL)
> + return err;
> + skb_reserve(skb, MAX_PHONET_HEADER);
> +
> + err = memcpy_fromiovec((void *)skb_put(skb, len), msg->msg_iov, len);
> + if (err < 0) {
> + kfree_skb(skb);
> + return err;
> + }
> +
> + /*
> + * Fill in the Phonet header and
> + * finally pass the packet forwards.
> + */
> + err = pn_skb_send(sk, skb, target);
> +
> + /* If ok, return len. */
> + return (err >= 0) ? len : err;
> +}
> +
> +static int pn_recvmsg(struct kiocb *iocb, struct sock *sk,
> + struct msghdr *msg, size_t len, int noblock,
> + int flags, int *addr_len)
> +{
> + struct sk_buff *skb = NULL;
> + struct sockaddr_pn sa;
> + int rval = -EOPNOTSUPP;
> + int copylen;
> +
> + if (flags & MSG_OOB)
> + goto out_nofree;
> +
> + if (addr_len)
> + *addr_len = sizeof(sa);
> +
> + skb = skb_recv_datagram(sk, flags, noblock, &rval);
> + if (skb == NULL)
> + goto out_nofree;
> +
> + pn_skb_get_src_sockaddr(skb, &sa);
> +
> + copylen = skb->len;
> + if (len < copylen) {
> + msg->msg_flags |= MSG_TRUNC;
> + copylen = len;
> + }
> +
> + rval = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copylen);
> + if (rval) {
> + rval = -EFAULT;
> + goto out;
> + }
> +
> + rval = (flags & MSG_TRUNC) ? skb->len : copylen;
> +
> + if (msg->msg_name != NULL)
> + memcpy(msg->msg_name, &sa, sizeof(struct sockaddr_pn));
> +
> +out:
> + skb_free_datagram(sk, skb);
> +
> +out_nofree:
> + return rval;
> +}
> +
> +/* Queue an skb for a sock. */
> +static int pn_backlog_rcv(struct sock *sk, struct sk_buff *skb)
> +{
> + int err = sock_queue_rcv_skb(sk, skb);
> + if (err < 0)
> + kfree_skb(skb);
> + return err;
> +}
> +
> +/* Module registration */
> +static struct proto pn_proto = {
> + .close = pn_sock_close,
> + .ioctl = pn_ioctl,
> + .init = pn_init,
> + .sendmsg = pn_sendmsg,
> + .recvmsg = pn_recvmsg,
> + .backlog_rcv = pn_backlog_rcv,
And here you even seem to use it :-)
> + .hash = pn_sock_hash,
> + .unhash = pn_sock_unhash,
> + .get_port = pn_sock_get_port,
> + .obj_size = sizeof(struct pn_sock),
> + .owner = THIS_MODULE,
> + .name = "PHONET",
> +};
> +
> +static struct phonet_protocol pn_dgram_proto = {
> + .ops = &phonet_dgram_ops,
> + .prot = &pn_proto,
> + .sock_type = SOCK_DGRAM,
> +};
> +
> +int __init isi_register(void)
> +{
> + return phonet_proto_register(PN_PROTO_PHONET, &pn_dgram_proto);
> +}
> +
> +void __exit isi_unregister(void)
> +{
> + phonet_proto_unregister(PN_PROTO_PHONET, &pn_dgram_proto);
> +}
> --
> 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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 13/14] Phonet: emit errors when a packet cannot be delivered locally
2008-09-16 15:08 ` [PATCH 13/14] Phonet: emit errors when a packet cannot be delivered locally Rémi Denis-Courmont
@ 2008-09-16 17:11 ` Arnaldo Carvalho de Melo
0 siblings, 0 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-09-16 17:11 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Em Tue, Sep 16, 2008 at 06:08:13PM +0300, Rémi Denis-Courmont escreveu:
> 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);
Check if you shouldn't be using skb_copy_to_linear_data
> + 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 *skb)
> +{
> + const struct phonethdr *ph = pn_hdr(skb);
> + struct phonet_device *pnd;
> +
> + if (!pskb_may_pull(skb, 3))
> + return 0;
> + if (skb->data[1] == 0xF0)
> + return 0;
> + if (skb->data[2] == 0x01 || skb->data[2] == 0x14)
> + return 0;
Try not to access skb->data directly, probably you would be better off
using some pn_hdr() like accessor that peeked at the mac_header, etc
> + spin_lock(&pndevs.lock);
> + pnd = __phonet_get_by_index(skb->dev->ifindex);
> + if (!pnd
> + || !phonet_dev2addr(pnd, ph->rdev & 0xFC, PN_FIND_EXACT)) {
> + spin_unlock(&pndevs.lock);
> + return 0;
> + }
> + spin_unlock(&pndevs.lock);
> + return 1;
> +}
> +
> +static int send_obj_unreachable(struct sk_buff *rskb)
> +{
> + struct phonethdr *oph = pn_hdr(rskb);
> + uint8_t data[8];
> +
> + BUG_ON(skb_headlen(rskb) < 2);
> + data[0] = rskb->data[0];
> + data[1] = 0xF0;
> + data[2] = 0x14;
> + data[3] = rskb->data[1];
> + data[4] = 0x00;
> + data[5] = 0x00;
> + data[6] = 0x00;
> + data[7] = 0x00;
Couldn't this be built using some relevant struct, etc?
> + return pn_raw_send(data, sizeof(data), rskb->dev,
> + pn_object(oph->sdev, oph->sobj),
> + pn_object(oph->rdev, oph->robj),
> + oph->function);
> +}
> +
> +static int send_reset_indications(struct sk_buff *rskb)
> +{
> + struct phonethdr *oph = pn_hdr(rskb);
> + uint8_t data[4] = { 0x00, 0x10, 0x00, 0x00 };
> +
> + return pn_raw_send(data, sizeof(data), rskb->dev,
> + pn_object(oph->sdev, 0x00),
> + pn_object(oph->rdev, oph->robj), 0x10);
> +}
> +
> +
> /* packet type functions */
>
> /*
> @@ -269,8 +338,13 @@ static int phonet_rcv(struct sk_buff *skb, struct net_device *dev,
> goto out; /* currently, we cannot be device 0 */
>
> sk = pn_find_sock_by_sa(&sa);
> - if (sk == NULL)
> + if (sk == NULL) {
> + if (can_respond(skb)) {
> + send_obj_unreachable(skb);
> + send_reset_indications(skb);
> + }
> goto out;
> + }
>
> /* Push data to the socket (or other sockets connected to it). */
> err = pn_sk(sk)->handler(sk, skb);
> --
> 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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 09/14] Phonet: allocate and initialize new sockets
2008-09-16 15:08 ` [PATCH 09/14] Phonet: allocate and initialize new sockets Rémi Denis-Courmont
2008-09-16 16:53 ` Arnaldo Carvalho de Melo
@ 2008-09-16 18:42 ` Pavel Emelyanov
2008-09-17 8:30 ` Rémi Denis-Courmont
1 sibling, 1 reply; 41+ messages in thread
From: Pavel Emelyanov @ 2008-09-16 18:42 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
> @@ -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;
> + }
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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 00/14] [RFC] Phonet protocol stack
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (13 preceding siblings ...)
2008-09-16 15:08 ` [PATCH 14/14] Phonet: kernel documentation Rémi Denis-Courmont
@ 2008-09-16 20:09 ` Marcel Holtmann
2008-09-17 13:52 ` Rémi Denis-Courmont
2008-09-17 4:15 ` Dan Williams
15 siblings, 1 reply; 41+ messages in thread
From: Marcel Holtmann @ 2008-09-16 20:09 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Hi Remi,
> 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.
nice to see that this finally becomes open source.
> 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.
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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 00/14] [RFC] Phonet protocol stack
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
` (14 preceding siblings ...)
2008-09-16 20:09 ` [PATCH 00/14] [RFC] Phonet protocol stack Marcel Holtmann
@ 2008-09-17 4:15 ` Dan Williams
2008-09-19 7:25 ` Rémi Denis-Courmont
15 siblings, 1 reply; 41+ messages in thread
From: Dan Williams @ 2008-09-17 4:15 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
On Tue, 2008-09-16 at 17:57 +0300, Rémi Denis-Courmont wrote:
> 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.
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...
Dan
> 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,
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/14] Phonet global definitions
2008-09-16 15:08 ` [PATCH 01/14] Phonet global definitions Rémi Denis-Courmont
@ 2008-09-17 4:31 ` Simon Horman
2008-09-17 11:05 ` Rémi Denis-Courmont
0 siblings, 1 reply; 41+ messages in thread
From: Simon Horman @ 2008-09-17 4:31 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
On Tue, Sep 16, 2008 at 06:08:01PM +0300, Rémi Denis-Courmont wrote:
> 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.
> + *
> + * 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 LINUX_PHONET_H
> +#define LINUX_PHONET_H
> +
> +/* Automatic protocol selection */
> +#define PN_PROTO_TRANSPORT 0
> +/* Phonet datagram socket */
> +#define PN_PROTO_PHONET 1
> +#define PHONET_NPROTO 2
> +
> +#define PNADDR_ANY 0
> +#define PNPORT_RESOURCE_ROUTING 0
> +
> +/* Phonet protocol header */
> +struct phonethdr {
> + uint8_t rdev;
> + uint8_t sdev;
> + uint8_t function;
> + uint16_t length;
> + uint8_t robj;
> + uint8_t sobj;
> +} __attribute__((packed));
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.
Ditto below.
> +
> +/* Phonet message */
> +struct phonetmsg {
> + struct phonethdr ph;
> + uint8_t data[0];
> +};
> +
> +/* Phonet socket address structure */
> +struct sockaddr_pn {
> + sa_family_t spn_family;
> + uint8_t spn_obj;
> + uint8_t spn_dev;
> + uint8_t spn_resource;
> + uint8_t spn_zero[sizeof(struct sockaddr)
> + - sizeof(sa_family_t) - 3 * sizeof(uint8_t)];
> +} __attribute__ ((packed));
> +
> +static inline uint16_t pn_object(uint8_t addr, uint16_t port)
> +{
> + return (addr << 8) | (port & 0x3ff);
> +}
> +
> +static inline uint8_t pn_obj(uint16_t handle)
> +{
> + return handle & 0xff;
> +}
> +
> +static inline uint8_t pn_dev(uint16_t handle)
> +{
> + return handle >> 8;
> +}
> +
> +static inline uint16_t pn_port(uint16_t handle)
> +{
> + return handle & 0x3ff;
> +}
> +
> +static inline uint8_t pn_addr(uint16_t handle)
> +{
> + return (handle >> 8) & 0xfc;
> +}
> +
> +static inline void pn_sockaddr_set_addr(struct sockaddr_pn *spn, uint8_t addr)
> +{
> + spn->spn_dev &= 0x03;
> + spn->spn_dev |= addr & 0xfc;
> +}
> +
> +static inline void pn_sockaddr_set_port(struct sockaddr_pn *spn,
> + uint16_t port)
> +{
> + spn->spn_dev &= 0xfc;
> + spn->spn_dev |= (port >> 8) & 0x03;
> + spn->spn_obj = port & 0xff;
> +}
> +
> +static inline void pn_sockaddr_set_object(struct sockaddr_pn *spn,
> + uint16_t handle)
> +{
> + spn->spn_dev = pn_dev(handle);
> + spn->spn_obj = pn_obj(handle);
> +}
> +
> +static inline void pn_sockaddr_set_resource(struct sockaddr_pn *spn,
> + uint8_t resource)
> +{
> + spn->spn_resource = resource;
> +}
> +
> +static inline uint8_t pn_sockaddr_get_addr(const struct sockaddr_pn *spn)
> +{
> + return spn->spn_dev & 0xfc;
> +}
> +
> +static inline uint16_t pn_sockaddr_get_port(const struct sockaddr_pn *spn)
> +{
> + return ((spn->spn_dev & 0x03) << 8) | spn->spn_obj;
> +}
> +
> +static inline uint16_t pn_sockaddr_get_object(const struct sockaddr_pn *spn)
> +{
> + return pn_object(spn->spn_dev, spn->spn_obj);
> +}
> +
> +static inline uint8_t pn_sockaddr_get_resource(const struct sockaddr_pn *spn)
> +{
> + return spn->spn_resource;
> +}
> +
> +#endif
> diff --git a/include/linux/rtnetlink.h b/include/linux/rtnetlink.h
> index ca643b1..2b3d51c 100644
> --- a/include/linux/rtnetlink.h
> +++ b/include/linux/rtnetlink.h
> @@ -582,6 +582,10 @@ enum rtnetlink_groups {
> #define RTNLGRP_IPV6_RULE RTNLGRP_IPV6_RULE
> RTNLGRP_ND_USEROPT,
> #define RTNLGRP_ND_USEROPT RTNLGRP_ND_USEROPT
> + RTNLGRP_PHONET_IFADDR,
> +#define RTNLGRP_PHONET_IFADDR RTNLGRP_PHONET_IFADDR
> + RTNLGRP_PHONET_ROUTE,
> +#define RTNLGRP_PHONET_ROUTE RTNLGRP_PHONET_ROUTE
> __RTNLGRP_MAX
> };
> #define RTNLGRP_MAX (__RTNLGRP_MAX - 1)
> diff --git a/include/linux/socket.h b/include/linux/socket.h
> index dc5086f..818ca33 100644
> --- a/include/linux/socket.h
> +++ b/include/linux/socket.h
> @@ -190,7 +190,8 @@ struct ucred {
> #define AF_IUCV 32 /* IUCV sockets */
> #define AF_RXRPC 33 /* RxRPC sockets */
> #define AF_ISDN 34 /* mISDN sockets */
> -#define AF_MAX 35 /* For now.. */
> +#define AF_PHONET 35 /* Phonet sockets */
> +#define AF_MAX 36 /* For now.. */
>
> /* Protocol families, same as address families. */
> #define PF_UNSPEC AF_UNSPEC
> @@ -227,6 +228,7 @@ struct ucred {
> #define PF_IUCV AF_IUCV
> #define PF_RXRPC AF_RXRPC
> #define PF_ISDN AF_ISDN
> +#define PF_PHONET AF_PHONET
> #define PF_MAX AF_MAX
>
> /* Maximum queue length specifiable by listen. */
> diff --git a/net/core/sock.c b/net/core/sock.c
> index d823978..4ce2145 100644
> --- a/net/core/sock.c
> +++ b/net/core/sock.c
> @@ -154,7 +154,8 @@ static const char *af_family_key_strings[AF_MAX+1] = {
> "sk_lock-AF_PPPOX" , "sk_lock-AF_WANPIPE" , "sk_lock-AF_LLC" ,
> "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" ,
> "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" ,
> - "sk_lock-AF_RXRPC" , "sk_lock-AF_MISDN" , "sk_lock-AF_MAX"
> + "sk_lock-AF_RXRPC" , "sk_lock-AF_MISDN" , "sk_lock-AF_PHONET" ,
> + "sk_lock-AF_MAX"
> };
> static const char *af_family_slock_key_strings[AF_MAX+1] = {
> "slock-AF_UNSPEC", "slock-AF_UNIX" , "slock-AF_INET" ,
> @@ -168,7 +169,8 @@ static const char *af_family_slock_key_strings[AF_MAX+1] = {
> "slock-AF_PPPOX" , "slock-AF_WANPIPE" , "slock-AF_LLC" ,
> "slock-27" , "slock-28" , "slock-AF_CAN" ,
> "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" ,
> - "slock-AF_RXRPC" , "slock-AF_MISDN" , "slock-AF_MAX"
> + "slock-AF_RXRPC" , "slock-AF_MISDN" , "slock-AF_PHONET" ,
> + "slock-AF_MAX"
> };
> static const char *af_family_clock_key_strings[AF_MAX+1] = {
> "clock-AF_UNSPEC", "clock-AF_UNIX" , "clock-AF_INET" ,
> @@ -182,7 +184,8 @@ static const char *af_family_clock_key_strings[AF_MAX+1] = {
> "clock-AF_PPPOX" , "clock-AF_WANPIPE" , "clock-AF_LLC" ,
> "clock-27" , "clock-28" , "clock-AF_CAN" ,
> "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" ,
> - "clock-AF_RXRPC" , "clock-AF_MISDN" , "clock-AF_MAX"
> + "clock-AF_RXRPC" , "clock-AF_MISDN" , "clock-AF_PHONET" ,
> + "clock-AF_MAX"
> };
> #endif
>
> --
> 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
--
Simon Horman
VA Linux Systems Japan K.K., Sydney, Australia Satellite Office
H: www.vergenet.net/~horms/ W: www.valinux.co.jp/en
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 03/14] Phonet: build the net/phonet/ directory
2008-09-16 16:06 ` Arnaldo Carvalho de Melo
@ 2008-09-17 4:52 ` Simon Horman
2008-09-17 8:44 ` Rémi Denis-Courmont
0 siblings, 1 reply; 41+ messages in thread
From: Simon Horman @ 2008-09-17 4:52 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, Rémi Denis-Courmont, netdev
On Tue, Sep 16, 2008 at 01:06:55PM -0300, Arnaldo Carvalho de Melo wrote:
> Em Tue, Sep 16, 2008 at 06:08:03PM +0300, Rémi Denis-Courmont escreveu:
> > Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
> > ---
> > net/Kconfig | 1 +
> > net/Makefile | 1 +
> > 2 files changed, 2 insertions(+), 0 deletions(-)
>
> Can't this be combined with 2/14?
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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 09/14] Phonet: allocate and initialize new sockets
2008-09-16 18:42 ` Pavel Emelyanov
@ 2008-09-17 8:30 ` Rémi Denis-Courmont
2008-09-19 10:14 ` Pavel Emelyanov
0 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-17 8:30 UTC (permalink / raw)
To: ext Pavel Emelyanov; +Cc: netdev
Hello,
On Tuesday 16 September 2008 21:42:52 ext Pavel Emelyanov, you wrote:
> > @@ -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;
> > + }
>
> 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,
I expect pn_socket_create() should forbid this, no?
if (net != &init_net)
return -EAFNOSUPPORT;
/* ... */
sk = sk_alloc(net, PF_PHONET, GFP_KERNEL, pnp->prot);
> the list of devices is global,
Hmmm, good point. Should I forbid adding an address to devices outside the
initial namespace? what about a device with an existing address being
migrated?
> whilst the sysctls are visible in init_net only...
Regards,
--
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 03/14] Phonet: build the net/phonet/ directory
2008-09-17 4:52 ` Simon Horman
@ 2008-09-17 8:44 ` Rémi Denis-Courmont
0 siblings, 0 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-17 8:44 UTC (permalink / raw)
To: ext Simon Horman; +Cc: Arnaldo Carvalho de Melo, netdev
On Wednesday 17 September 2008 07:52:25 ext Simon Horman, you wrote:
> On Tue, Sep 16, 2008 at 01:06:55PM -0300, Arnaldo Carvalho de Melo wrote:
> > Em Tue, Sep 16, 2008 at 06:08:03PM +0300, Rémi Denis-Courmont escreveu:
> > > Signed-off-by: Remi Denis-Courmont <remi.denis-courmont@nokia.com>
> > > ---
> > > net/Kconfig | 1 +
> > > net/Makefile | 1 +
> > > 2 files changed, 2 insertions(+), 0 deletions(-)
> >
> > Can't this be combined with 2/14?
>
> 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.
Woops. I'll switch to 1, 4, 2+3, 5...
--
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 04/14] Phonet: PF_PHONET protocol family support
2008-09-16 16:17 ` Arnaldo Carvalho de Melo
@ 2008-09-17 10:48 ` Rémi Denis-Courmont
0 siblings, 0 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-17 10:48 UTC (permalink / raw)
To: ext Arnaldo Carvalho de Melo; +Cc: netdev
Hello,
On Tuesday 16 September 2008 19:17:47 ext Arnaldo Carvalho de Melo, you wrote:
> > +/* Protocols in Phonet protocol family. */
> > +struct phonet_protocol {
> > + struct proto *prot;
> > + int sock_type;
> > +};
>
> 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?
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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 01/14] Phonet global definitions
2008-09-17 4:31 ` Simon Horman
@ 2008-09-17 11:05 ` Rémi Denis-Courmont
0 siblings, 0 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-17 11:05 UTC (permalink / raw)
To: ext Simon Horman; +Cc: netdev
On Wednesday 17 September 2008 07:31:42 ext Simon Horman, you wrote:
> > +/* Phonet protocol header */
> > +struct phonethdr {
> > + uint8_t rdev;
> > + uint8_t sdev;
> > + uint8_t function;
> > + uint16_t length;
> > + uint8_t robj;
> > + uint8_t sobj;
> > +} __attribute__((packed));
>
> 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. Ditto below.
Now, that explains things. I'll fix all of these, thanks.
--
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 00/14] [RFC] Phonet protocol stack
2008-09-16 20:09 ` [PATCH 00/14] [RFC] Phonet protocol stack Marcel Holtmann
@ 2008-09-17 13:52 ` Rémi Denis-Courmont
0 siblings, 0 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-17 13:52 UTC (permalink / raw)
To: ext Marcel Holtmann; +Cc: netdev
Hello,
On Tuesday 16 September 2008 23:09:04 ext Marcel Holtmann, you wrote:
> > 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.
>
> 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?
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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 08/14] Phonet: receive path socket lookup
2008-09-16 16:52 ` Arnaldo Carvalho de Melo
@ 2008-09-19 6:20 ` Rémi Denis-Courmont
0 siblings, 0 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-19 6:20 UTC (permalink / raw)
To: ext Arnaldo Carvalho de Melo; +Cc: netdev
On Tuesday 16 September 2008 19:52:05 ext Arnaldo Carvalho de Melo, you wrote:
> > + /* Push data to the socket (or other sockets connected to it). */
> > + err = pn_sk(sk)->handler(sk, skb);
>
> wouldn't be nice to use sk_backlog_rcv() and sk_receive_skb()?
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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 10/14] Phonet: Phonet datagram transport protocol
2008-09-16 17:06 ` Arnaldo Carvalho de Melo
@ 2008-09-19 6:33 ` Rémi Denis-Courmont
2008-09-19 15:24 ` [PATCH]: net: Use hton[sl]() was " Arnaldo Carvalho de Melo
0 siblings, 1 reply; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-19 6:33 UTC (permalink / raw)
To: ext Arnaldo Carvalho de Melo; +Cc: netdev
On Tuesday 16 September 2008 20:06:44 ext Arnaldo Carvalho de Melo, you wrote:
> > +/*
> > + * 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) {
>
> wow, what a magic number! :-)
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
transmitting above the MTU?
> > + skb_reset_transport_header(skb);
> > + WARN_ON(skb_headroom(skb) & 1); /* HW assumes word alignment */
> > + ph = (struct phonethdr *)skb_push(skb, sizeof(struct phonethdr));
> > + skb_reset_network_header(skb);
>
> Here you could just use:
>
> ph = (struct phonethdr *)skb_network_header(skb);
>
> or even just:
>
> ph = pn_hdr(skb);
>
> as other protocols such as IP do (see ip_hdr())
Right.
> > + ph->rdev = pn_dev(dst);
> > + ph->sdev = pn_dev(src);
> > + ph->function = res;
> > + ph->length = __cpu_to_be16(skb->len + 2 - sizeof(*ph));
> > + ph->robj = pn_obj(dst);
> > + ph->sobj = pn_obj(src);
> > +
> > + skb->protocol = __constant_htons(ETH_P_PHONET);
>
> No need for __constant_htons(CONSTANT), htons will do the right thing
> and the code will be shorter, clearer.
Ok. There are quite many of these in net/ though... is that reserved for
switch/case only?
(...)
> > +static int pn_ioctl(struct sock *sk, int cmd, unsigned long arg)
> > +{
> > + struct sk_buff *skb;
> > + int answ;
> > +
> > + switch (cmd) {
> > + case SIOCINQ:
> > + spin_lock_bh(&sk->sk_receive_queue.lock);
> > + skb = skb_peek(&sk->sk_receive_queue);
> > + answ = skb ? skb->len : 0;
> > + spin_unlock_bh(&sk->sk_receive_queue.lock);
> > + return put_user(answ, (int __user *)arg);
>
> Why not use lock_sock/release_sock as tcp?
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
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 00/14] [RFC] Phonet protocol stack
2008-09-17 4:15 ` Dan Williams
@ 2008-09-19 7:25 ` Rémi Denis-Courmont
0 siblings, 0 replies; 41+ messages in thread
From: Rémi Denis-Courmont @ 2008-09-19 7:25 UTC (permalink / raw)
To: ext Dan Williams; +Cc: netdev
Hello,
On Wednesday 17 September 2008 07:15:48 ext Dan Williams, you wrote:
> Do you have any documentation or examples of how userspace uses this
> interface?
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
better alternative.
> 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...
Regards,
--
Rémi Denis-Courmont
Maemo Software, Nokia Devices R&D
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH 09/14] Phonet: allocate and initialize new sockets
2008-09-17 8:30 ` Rémi Denis-Courmont
@ 2008-09-19 10:14 ` Pavel Emelyanov
0 siblings, 0 replies; 41+ messages in thread
From: Pavel Emelyanov @ 2008-09-19 10:14 UTC (permalink / raw)
To: Rémi Denis-Courmont; +Cc: netdev
Rémi Denis-Courmont wrote:
> Hello,
>
> On Tuesday 16 September 2008 21:42:52 ext Pavel Emelyanov, you wrote:
>>> @@ -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;
>>> + }
>> 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,
>
> I expect pn_socket_create() should forbid this, no?
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
to, I will answer - yes, please, ban this protocol for !init_ns :)
> if (net != &init_net)
> return -EAFNOSUPPORT;
> /* ... */
> sk = sk_alloc(net, PF_PHONET, GFP_KERNEL, pnp->prot);
>
>> the list of devices is global,
>
> Hmmm, good point. Should I forbid adding an address to devices outside the
> initial namespace? what about a device with an existing address being
> migrated?
>
>> whilst the sysctls are visible in init_net only...
>
> Regards,
>
^ permalink raw reply [flat|nested] 41+ messages in thread
* [PATCH]: net: Use hton[sl]() was Re: [PATCH 10/14] Phonet: Phonet datagram transport protocol
2008-09-19 6:33 ` Rémi Denis-Courmont
@ 2008-09-19 15:24 ` Arnaldo Carvalho de Melo
2008-09-21 5:21 ` David Miller
2008-11-14 8:32 ` Piet Delaney
0 siblings, 2 replies; 41+ messages in thread
From: Arnaldo Carvalho de Melo @ 2008-09-19 15:24 UTC (permalink / raw)
To: David S. Miller; +Cc: Rémi Denis-Courmont, netdev
Em Fri, Sep 19, 2008 at 09:33:33AM +0300, Rémi Denis-Courmont escreveu:
> On Tuesday 16 September 2008 20:06:44 ext Arnaldo Carvalho de Melo, you wrote:
> > > + ph->robj = pn_obj(dst);
> > > + ph->sobj = pn_obj(src);
> > > +
> > > + skb->protocol = __constant_htons(ETH_P_PHONET);
> >
> > No need for __constant_htons(CONSTANT), htons will do the right thing
> > and the code will be shorter, clearer.
>
> Ok. There are quite many of these in net/ though... is that reserved for
> switch/case only?
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 b/net/core/dev.c
index f48d1b2..fdfc4b6 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1675,13 +1675,13 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
}
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
ip_proto = ip_hdr(skb)->protocol;
addr1 = ip_hdr(skb)->saddr;
addr2 = ip_hdr(skb)->daddr;
ihl = ip_hdr(skb)->ihl;
break;
- case __constant_htons(ETH_P_IPV6):
+ case htons(ETH_P_IPV6):
ip_proto = ipv6_hdr(skb)->nexthdr;
addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
index a80839b..647a9ed 100644
--- a/net/ethernet/eth.c
+++ b/net/ethernet/eth.c
@@ -129,7 +129,7 @@ int eth_rebuild_header(struct sk_buff *skb)
switch (eth->h_proto) {
#ifdef CONFIG_INET
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
return arp_find(eth->h_dest, skb);
#endif
default:
diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
index ece748d..958abf3 100644
--- a/net/ipv4/ipvs/ip_vs_core.c
+++ b/net/ipv4/ipvs/ip_vs_core.c
@@ -938,7 +938,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
EnterFunction(11);
- af = (skb->protocol == __constant_htons(ETH_P_IP)) ? AF_INET : AF_INET6;
+ af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
if (skb->ipvs_property)
return NF_ACCEPT;
@@ -1258,7 +1258,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
struct ip_vs_conn *cp;
int ret, restart, af;
- af = (skb->protocol == __constant_htons(ETH_P_IP)) ? AF_INET : AF_INET6;
+ af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
index 17c7b09..64ce3d3 100644
--- a/net/ipv6/ip6_tunnel.c
+++ b/net/ipv6/ip6_tunnel.c
@@ -1050,10 +1050,10 @@ ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
}
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
ret = ip4ip6_tnl_xmit(skb, dev);
break;
- case __constant_htons(ETH_P_IPV6):
+ case htons(ETH_P_IPV6):
ret = ip6ip6_tnl_xmit(skb, dev);
break;
default:
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 7229e95..5966b9f 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -39,7 +39,7 @@ static unsigned int classify_1d(struct sk_buff *skb)
return skb->priority - 256;
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
dscp = ip_hdr(skb)->tos & 0xfc;
break;
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 8f63a1a..0ebaff6 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -67,9 +67,9 @@ static inline u32 addr_fold(void *addr)
static u32 flow_get_src(const struct sk_buff *skb)
{
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
return ntohl(ip_hdr(skb)->saddr);
- case __constant_htons(ETH_P_IPV6):
+ case htons(ETH_P_IPV6):
return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]);
default:
return addr_fold(skb->sk);
@@ -79,9 +79,9 @@ static u32 flow_get_src(const struct sk_buff *skb)
static u32 flow_get_dst(const struct sk_buff *skb)
{
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
return ntohl(ip_hdr(skb)->daddr);
- case __constant_htons(ETH_P_IPV6):
+ case htons(ETH_P_IPV6):
return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]);
default:
return addr_fold(skb->dst) ^ (__force u16)skb->protocol;
@@ -91,9 +91,9 @@ static u32 flow_get_dst(const struct sk_buff *skb)
static u32 flow_get_proto(const struct sk_buff *skb)
{
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
return ip_hdr(skb)->protocol;
- case __constant_htons(ETH_P_IPV6):
+ case htons(ETH_P_IPV6):
return ipv6_hdr(skb)->nexthdr;
default:
return 0;
@@ -120,7 +120,7 @@ static u32 flow_get_proto_src(const struct sk_buff *skb)
u32 res = 0;
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP): {
+ case htons(ETH_P_IP): {
struct iphdr *iph = ip_hdr(skb);
if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
@@ -128,7 +128,7 @@ static u32 flow_get_proto_src(const struct sk_buff *skb)
res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4));
break;
}
- case __constant_htons(ETH_P_IPV6): {
+ case htons(ETH_P_IPV6): {
struct ipv6hdr *iph = ipv6_hdr(skb);
if (has_ports(iph->nexthdr))
@@ -147,7 +147,7 @@ static u32 flow_get_proto_dst(const struct sk_buff *skb)
u32 res = 0;
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP): {
+ case htons(ETH_P_IP): {
struct iphdr *iph = ip_hdr(skb);
if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
@@ -155,7 +155,7 @@ static u32 flow_get_proto_dst(const struct sk_buff *skb)
res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2));
break;
}
- case __constant_htons(ETH_P_IPV6): {
+ case htons(ETH_P_IPV6): {
struct ipv6hdr *iph = ipv6_hdr(skb);
if (has_ports(iph->nexthdr))
@@ -213,9 +213,9 @@ static u32 flow_get_nfct(const struct sk_buff *skb)
static u32 flow_get_nfct_src(const struct sk_buff *skb)
{
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
return ntohl(CTTUPLE(skb, src.u3.ip));
- case __constant_htons(ETH_P_IPV6):
+ case htons(ETH_P_IPV6):
return ntohl(CTTUPLE(skb, src.u3.ip6[3]));
}
fallback:
@@ -225,9 +225,9 @@ fallback:
static u32 flow_get_nfct_dst(const struct sk_buff *skb)
{
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
return ntohl(CTTUPLE(skb, dst.u3.ip));
- case __constant_htons(ETH_P_IPV6):
+ case htons(ETH_P_IPV6):
return ntohl(CTTUPLE(skb, dst.u3.ip6[3]));
}
fallback:
diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
index edd1298..ba43aab 100644
--- a/net/sched/sch_dsmark.c
+++ b/net/sched/sch_dsmark.c
@@ -202,7 +202,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
if (p->set_tc_index) {
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
if (skb_cow_head(skb, sizeof(struct iphdr)))
goto drop;
@@ -210,7 +210,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
& ~INET_ECN_MASK;
break;
- case __constant_htons(ETH_P_IPV6):
+ case htons(ETH_P_IPV6):
if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
goto drop;
@@ -289,11 +289,11 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
pr_debug("index %d->%d\n", skb->tc_index, index);
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
ipv4_change_dsfield(ip_hdr(skb), p->mask[index],
p->value[index]);
break;
- case __constant_htons(ETH_P_IPV6):
+ case htons(ETH_P_IPV6):
ipv6_change_dsfield(ipv6_hdr(skb), p->mask[index],
p->value[index]);
break;
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 6e041d1..fe1508e 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -119,7 +119,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
u32 h, h2;
switch (skb->protocol) {
- case __constant_htons(ETH_P_IP):
+ case htons(ETH_P_IP):
{
const struct iphdr *iph = ip_hdr(skb);
h = iph->daddr;
@@ -134,7 +134,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
h2 ^= *(((u32*)iph) + iph->ihl);
break;
}
- case __constant_htons(ETH_P_IPV6):
+ case htons(ETH_P_IPV6):
{
struct ipv6hdr *iph = ipv6_hdr(skb);
h = iph->daddr.s6_addr32[3];
diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
index e55427f..5c1954d 100644
--- a/net/sunrpc/xprtrdma/rpc_rdma.c
+++ b/net/sunrpc/xprtrdma/rpc_rdma.c
@@ -769,7 +769,7 @@ repost:
/* check for expected message types */
/* The order of some of these tests is important. */
switch (headerp->rm_type) {
- case __constant_htonl(RDMA_MSG):
+ case htonl(RDMA_MSG):
/* never expect read chunks */
/* never expect reply chunks (two ways to check) */
/* never expect write chunks without having offered RDMA */
@@ -802,7 +802,7 @@ repost:
rpcrdma_inline_fixup(rqst, (char *)iptr, rep->rr_len);
break;
- case __constant_htonl(RDMA_NOMSG):
+ case htonl(RDMA_NOMSG):
/* never expect read or write chunks, always reply chunks */
if (headerp->rm_body.rm_chunks[0] != xdr_zero ||
headerp->rm_body.rm_chunks[1] != xdr_zero ||
^ permalink raw reply related [flat|nested] 41+ messages in thread
* Re: [PATCH]: net: Use hton[sl]() was Re: [PATCH 10/14] Phonet: Phonet datagram transport protocol
2008-09-19 15:24 ` [PATCH]: net: Use hton[sl]() was " Arnaldo Carvalho de Melo
@ 2008-09-21 5:21 ` David Miller
2008-11-14 8:32 ` Piet Delaney
1 sibling, 0 replies; 41+ messages in thread
From: David Miller @ 2008-09-21 5:21 UTC (permalink / raw)
To: acme; +Cc: remi.denis-courmont, netdev
From: Arnaldo Carvalho de Melo <acme@redhat.com>
Date: Fri, 19 Sep 2008 12:24:48 -0300
> David, the following patch converts what is in net-next-2.6 net/ now:
...
> net: Use hton[sl]() instead of __constant_hton[sl]() where applicable
>
> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Applied, thanks Arnaldo.
^ permalink raw reply [flat|nested] 41+ messages in thread
* Re: [PATCH]: net: Use hton[sl]() was Re: [PATCH 10/14] Phonet: Phonet datagram transport protocol
2008-09-19 15:24 ` [PATCH]: net: Use hton[sl]() was " Arnaldo Carvalho de Melo
2008-09-21 5:21 ` David Miller
@ 2008-11-14 8:32 ` Piet Delaney
1 sibling, 0 replies; 41+ messages in thread
From: Piet Delaney @ 2008-11-14 8:32 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo, netdev
Cc: David S. Miller, Rémi Denis-Courmont
Arnaldo Carvalho de Melo wrote:
> Em Fri, Sep 19, 2008 at 09:33:33AM +0300, Rémi Denis-Courmont escreveu:
>> On Tuesday 16 September 2008 20:06:44 ext Arnaldo Carvalho de Melo, you wrote:
>>>> + ph->robj = pn_obj(dst);
>>>> + ph->sobj = pn_obj(src);
>>>> +
>>>> + skb->protocol = __constant_htons(ETH_P_PHONET);
>>> No need for __constant_htons(CONSTANT), htons will do the right thing
>>> and the code will be shorter, clearer.
>> Ok. There are quite many of these in net/ though... is that reserved for
>> switch/case only?
>
> Nope, they should only be used when initializing static variables.
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.
-piet
>
> 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 b/net/core/dev.c
> index f48d1b2..fdfc4b6 100644
> --- a/net/core/dev.c
> +++ b/net/core/dev.c
> @@ -1675,13 +1675,13 @@ static u16 simple_tx_hash(struct net_device *dev, struct sk_buff *skb)
> }
>
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> ip_proto = ip_hdr(skb)->protocol;
> addr1 = ip_hdr(skb)->saddr;
> addr2 = ip_hdr(skb)->daddr;
> ihl = ip_hdr(skb)->ihl;
> break;
> - case __constant_htons(ETH_P_IPV6):
> + case htons(ETH_P_IPV6):
> ip_proto = ipv6_hdr(skb)->nexthdr;
> addr1 = ipv6_hdr(skb)->saddr.s6_addr32[3];
> addr2 = ipv6_hdr(skb)->daddr.s6_addr32[3];
> diff --git a/net/ethernet/eth.c b/net/ethernet/eth.c
> index a80839b..647a9ed 100644
> --- a/net/ethernet/eth.c
> +++ b/net/ethernet/eth.c
> @@ -129,7 +129,7 @@ int eth_rebuild_header(struct sk_buff *skb)
>
> switch (eth->h_proto) {
> #ifdef CONFIG_INET
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> return arp_find(eth->h_dest, skb);
> #endif
> default:
> diff --git a/net/ipv4/ipvs/ip_vs_core.c b/net/ipv4/ipvs/ip_vs_core.c
> index ece748d..958abf3 100644
> --- a/net/ipv4/ipvs/ip_vs_core.c
> +++ b/net/ipv4/ipvs/ip_vs_core.c
> @@ -938,7 +938,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb,
>
> EnterFunction(11);
>
> - af = (skb->protocol == __constant_htons(ETH_P_IP)) ? AF_INET : AF_INET6;
> + af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
>
> if (skb->ipvs_property)
> return NF_ACCEPT;
> @@ -1258,7 +1258,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb,
> struct ip_vs_conn *cp;
> int ret, restart, af;
>
> - af = (skb->protocol == __constant_htons(ETH_P_IP)) ? AF_INET : AF_INET6;
> + af = (skb->protocol == htons(ETH_P_IP)) ? AF_INET : AF_INET6;
>
> ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
>
> diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
> index 17c7b09..64ce3d3 100644
> --- a/net/ipv6/ip6_tunnel.c
> +++ b/net/ipv6/ip6_tunnel.c
> @@ -1050,10 +1050,10 @@ ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
> }
>
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> ret = ip4ip6_tnl_xmit(skb, dev);
> break;
> - case __constant_htons(ETH_P_IPV6):
> + case htons(ETH_P_IPV6):
> ret = ip6ip6_tnl_xmit(skb, dev);
> break;
> default:
> diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
> index 7229e95..5966b9f 100644
> --- a/net/mac80211/wme.c
> +++ b/net/mac80211/wme.c
> @@ -39,7 +39,7 @@ static unsigned int classify_1d(struct sk_buff *skb)
> return skb->priority - 256;
>
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> dscp = ip_hdr(skb)->tos & 0xfc;
> break;
>
> diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
> index 8f63a1a..0ebaff6 100644
> --- a/net/sched/cls_flow.c
> +++ b/net/sched/cls_flow.c
> @@ -67,9 +67,9 @@ static inline u32 addr_fold(void *addr)
> static u32 flow_get_src(const struct sk_buff *skb)
> {
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> return ntohl(ip_hdr(skb)->saddr);
> - case __constant_htons(ETH_P_IPV6):
> + case htons(ETH_P_IPV6):
> return ntohl(ipv6_hdr(skb)->saddr.s6_addr32[3]);
> default:
> return addr_fold(skb->sk);
> @@ -79,9 +79,9 @@ static u32 flow_get_src(const struct sk_buff *skb)
> static u32 flow_get_dst(const struct sk_buff *skb)
> {
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> return ntohl(ip_hdr(skb)->daddr);
> - case __constant_htons(ETH_P_IPV6):
> + case htons(ETH_P_IPV6):
> return ntohl(ipv6_hdr(skb)->daddr.s6_addr32[3]);
> default:
> return addr_fold(skb->dst) ^ (__force u16)skb->protocol;
> @@ -91,9 +91,9 @@ static u32 flow_get_dst(const struct sk_buff *skb)
> static u32 flow_get_proto(const struct sk_buff *skb)
> {
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> return ip_hdr(skb)->protocol;
> - case __constant_htons(ETH_P_IPV6):
> + case htons(ETH_P_IPV6):
> return ipv6_hdr(skb)->nexthdr;
> default:
> return 0;
> @@ -120,7 +120,7 @@ static u32 flow_get_proto_src(const struct sk_buff *skb)
> u32 res = 0;
>
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP): {
> + case htons(ETH_P_IP): {
> struct iphdr *iph = ip_hdr(skb);
>
> if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
> @@ -128,7 +128,7 @@ static u32 flow_get_proto_src(const struct sk_buff *skb)
> res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4));
> break;
> }
> - case __constant_htons(ETH_P_IPV6): {
> + case htons(ETH_P_IPV6): {
> struct ipv6hdr *iph = ipv6_hdr(skb);
>
> if (has_ports(iph->nexthdr))
> @@ -147,7 +147,7 @@ static u32 flow_get_proto_dst(const struct sk_buff *skb)
> u32 res = 0;
>
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP): {
> + case htons(ETH_P_IP): {
> struct iphdr *iph = ip_hdr(skb);
>
> if (!(iph->frag_off&htons(IP_MF|IP_OFFSET)) &&
> @@ -155,7 +155,7 @@ static u32 flow_get_proto_dst(const struct sk_buff *skb)
> res = ntohs(*(__be16 *)((void *)iph + iph->ihl * 4 + 2));
> break;
> }
> - case __constant_htons(ETH_P_IPV6): {
> + case htons(ETH_P_IPV6): {
> struct ipv6hdr *iph = ipv6_hdr(skb);
>
> if (has_ports(iph->nexthdr))
> @@ -213,9 +213,9 @@ static u32 flow_get_nfct(const struct sk_buff *skb)
> static u32 flow_get_nfct_src(const struct sk_buff *skb)
> {
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> return ntohl(CTTUPLE(skb, src.u3.ip));
> - case __constant_htons(ETH_P_IPV6):
> + case htons(ETH_P_IPV6):
> return ntohl(CTTUPLE(skb, src.u3.ip6[3]));
> }
> fallback:
> @@ -225,9 +225,9 @@ fallback:
> static u32 flow_get_nfct_dst(const struct sk_buff *skb)
> {
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> return ntohl(CTTUPLE(skb, dst.u3.ip));
> - case __constant_htons(ETH_P_IPV6):
> + case htons(ETH_P_IPV6):
> return ntohl(CTTUPLE(skb, dst.u3.ip6[3]));
> }
> fallback:
> diff --git a/net/sched/sch_dsmark.c b/net/sched/sch_dsmark.c
> index edd1298..ba43aab 100644
> --- a/net/sched/sch_dsmark.c
> +++ b/net/sched/sch_dsmark.c
> @@ -202,7 +202,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
>
> if (p->set_tc_index) {
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> if (skb_cow_head(skb, sizeof(struct iphdr)))
> goto drop;
>
> @@ -210,7 +210,7 @@ static int dsmark_enqueue(struct sk_buff *skb, struct Qdisc *sch)
> & ~INET_ECN_MASK;
> break;
>
> - case __constant_htons(ETH_P_IPV6):
> + case htons(ETH_P_IPV6):
> if (skb_cow_head(skb, sizeof(struct ipv6hdr)))
> goto drop;
>
> @@ -289,11 +289,11 @@ static struct sk_buff *dsmark_dequeue(struct Qdisc *sch)
> pr_debug("index %d->%d\n", skb->tc_index, index);
>
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> ipv4_change_dsfield(ip_hdr(skb), p->mask[index],
> p->value[index]);
> break;
> - case __constant_htons(ETH_P_IPV6):
> + case htons(ETH_P_IPV6):
> ipv6_change_dsfield(ipv6_hdr(skb), p->mask[index],
> p->value[index]);
> break;
> diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
> index 6e041d1..fe1508e 100644
> --- a/net/sched/sch_sfq.c
> +++ b/net/sched/sch_sfq.c
> @@ -119,7 +119,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
> u32 h, h2;
>
> switch (skb->protocol) {
> - case __constant_htons(ETH_P_IP):
> + case htons(ETH_P_IP):
> {
> const struct iphdr *iph = ip_hdr(skb);
> h = iph->daddr;
> @@ -134,7 +134,7 @@ static unsigned sfq_hash(struct sfq_sched_data *q, struct sk_buff *skb)
> h2 ^= *(((u32*)iph) + iph->ihl);
> break;
> }
> - case __constant_htons(ETH_P_IPV6):
> + case htons(ETH_P_IPV6):
> {
> struct ipv6hdr *iph = ipv6_hdr(skb);
> h = iph->daddr.s6_addr32[3];
> diff --git a/net/sunrpc/xprtrdma/rpc_rdma.c b/net/sunrpc/xprtrdma/rpc_rdma.c
> index e55427f..5c1954d 100644
> --- a/net/sunrpc/xprtrdma/rpc_rdma.c
> +++ b/net/sunrpc/xprtrdma/rpc_rdma.c
> @@ -769,7 +769,7 @@ repost:
> /* check for expected message types */
> /* The order of some of these tests is important. */
> switch (headerp->rm_type) {
> - case __constant_htonl(RDMA_MSG):
> + case htonl(RDMA_MSG):
> /* never expect read chunks */
> /* never expect reply chunks (two ways to check) */
> /* never expect write chunks without having offered RDMA */
> @@ -802,7 +802,7 @@ repost:
> rpcrdma_inline_fixup(rqst, (char *)iptr, rep->rr_len);
> break;
>
> - case __constant_htonl(RDMA_NOMSG):
> + case htonl(RDMA_NOMSG):
> /* never expect read or write chunks, always reply chunks */
> if (headerp->rm_body.rm_chunks[0] != xdr_zero ||
> headerp->rm_body.rm_chunks[1] != xdr_zero ||
> --
> 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
>
>
^ permalink raw reply [flat|nested] 41+ messages in thread
end of thread, other threads:[~2008-11-14 9:27 UTC | newest]
Thread overview: 41+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-16 14:57 [PATCH 00/14] [RFC] Phonet protocol stack Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 01/14] Phonet global definitions Rémi Denis-Courmont
2008-09-17 4:31 ` Simon Horman
2008-09-17 11:05 ` Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 02/14] Phonet: add CONFIG_PHONET Rémi Denis-Courmont
2008-09-16 16:06 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 03/14] Phonet: build the net/phonet/ directory Rémi Denis-Courmont
2008-09-16 16:06 ` Arnaldo Carvalho de Melo
2008-09-17 4:52 ` Simon Horman
2008-09-17 8:44 ` Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 04/14] Phonet: PF_PHONET protocol family support Rémi Denis-Courmont
2008-09-16 16:17 ` Arnaldo Carvalho de Melo
2008-09-17 10:48 ` Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 05/14] Phonet: network device and address handling Rémi Denis-Courmont
2008-09-16 16:41 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 06/14] Phonet: Netlink interface Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 07/14] Phonet: common socket glue Rémi Denis-Courmont
2008-09-16 16:50 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 08/14] Phonet: receive path socket lookup Rémi Denis-Courmont
2008-09-16 16:52 ` Arnaldo Carvalho de Melo
2008-09-19 6:20 ` Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 09/14] Phonet: allocate and initialize new sockets Rémi Denis-Courmont
2008-09-16 16:53 ` Arnaldo Carvalho de Melo
2008-09-16 18:42 ` Pavel Emelyanov
2008-09-17 8:30 ` Rémi Denis-Courmont
2008-09-19 10:14 ` Pavel Emelyanov
2008-09-16 15:08 ` [PATCH 10/14] Phonet: Phonet datagram transport protocol Rémi Denis-Courmont
2008-09-16 17:06 ` Arnaldo Carvalho de Melo
2008-09-19 6:33 ` Rémi Denis-Courmont
2008-09-19 15:24 ` [PATCH]: net: Use hton[sl]() was " Arnaldo Carvalho de Melo
2008-09-21 5:21 ` David Miller
2008-11-14 8:32 ` Piet Delaney
2008-09-16 15:08 ` [PATCH 11/14] Phonet: provide MAC header operations Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 12/14] Phonet: proc interface for port range Rémi Denis-Courmont
2008-09-16 15:08 ` [PATCH 13/14] Phonet: emit errors when a packet cannot be delivered locally Rémi Denis-Courmont
2008-09-16 17:11 ` Arnaldo Carvalho de Melo
2008-09-16 15:08 ` [PATCH 14/14] Phonet: kernel documentation Rémi Denis-Courmont
2008-09-16 20:09 ` [PATCH 00/14] [RFC] Phonet protocol stack Marcel Holtmann
2008-09-17 13:52 ` Rémi Denis-Courmont
2008-09-17 4:15 ` Dan Williams
2008-09-19 7:25 ` Rémi Denis-Courmont
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).