Thread (46 messages) 46 messages, 14 authors, 2009-06-21

Re: [PATCH 03/10] net: add IEEE 802.15.4 socket family implementation

flat view

From: Dmitry Eremin-Solenikov <hidden>
Date: 2009-06-04 11:16:59
Also in: lkml, netdev

On Wed, Jun 03, 2009 at 05:32:14PM -0700, Andrew Morton wrote:
On Mon,  1 Jun 2009 18:54:44 +0400
Dmitry Eremin-Solenikov [off-list ref] wrote:
quoted
Add support for communication over IEEE 802.15.4 networks. This implementation
is neither certified nor complete, but aims to that goal. This commit contains
only the socket interface for communication over IEEE 802.15.4 networks.
One can either send RAW datagrams or use SOCK_DGRAM to encapsulate data
inside normal IEEE 802.15.4 packets.

Configuration interface, drivers and software MAC 802.15.4 implementation will
follow.

Initial implementation was done by Maxim Gorbachyov, Maxim Osipov and Pavel
Smolensky as a research project at Siemens AG. Later the stack was heavily
reworked to better suit the linux networking model, and is now maitained
as an open project partially sponsored by Siemens.
Some drive-by nitpicking, and I saw a bug...
quoted
+	switch (addr->addr_type) {
+	case IEEE802154_ADDR_LONG:
+		rtnl_lock();
+		dev = dev_getbyhwaddr(net, ARPHRD_IEEE802154, addr->hwaddr);
+		if (dev)
+			dev_hold(dev);
+		rtnl_unlock();
+		break;
+	case IEEE802154_ADDR_SHORT:
+		if (addr->pan_id != 0xffff && addr->short_addr != IEEE802154_ADDR_UNDEF && addr->short_addr != 0xffff) {
+			struct net_device *tmp;
+
+			rtnl_lock();
+
+			for_each_netdev(net, tmp) {
+				if (tmp->type == ARPHRD_IEEE802154) {
+					if (IEEE802154_MLME_OPS(tmp)->get_pan_id(tmp) == addr->pan_id
+					  && IEEE802154_MLME_OPS(tmp)->get_short_addr(tmp) == addr->short_addr) {
You must use very wide xterms :(
~120 chars in width :)  We prefer to have a single code line split between
several screen lines, rather than split it manually in some weird places
just to justify width of 80 chars.
quoted
+						dev = tmp;
+						dev_hold(dev);
+						break;
+					}
+				}
+			}
+
+			rtnl_unlock();
+		}
+		break;
+	default:
+		pr_warning("Unsupported ieee802154 address type: %d\n", addr->addr_type);
+		break;
+	}
+
+	return dev;
+}
+

...

+static int ieee802154_create(struct net *net, struct socket *sock, int protocol)
+{
+	struct sock *sk;
+	int rc;
+	struct proto *proto;
+	const struct proto_ops *ops;
+
+	/* FIXME: init_net */
+	if (net != &init_net)
+		return -EAFNOSUPPORT;
yeah, I was going to ask about that.  What's the problem here?
The FIXME was dedicated to the fact that I didn't understand what is
this. The code fragment is c&p from lots of examples of similar code
(check can, appletalk, etc. for example)
quoted
+	switch (sock->type) {
+	case SOCK_RAW:
+		proto = &ieee802154_raw_prot;
+		ops = &ieee802154_raw_ops;
+		break;
+	case SOCK_DGRAM:
+		proto = &ieee802154_dgram_prot;
+		ops = &ieee802154_dgram_ops;
+		break;
+	default:
+		rc = -ESOCKTNOSUPPORT;
+		goto out;
+	}
+
+	rc = -ENOMEM;
+	sk = sk_alloc(net, PF_IEEE802154, GFP_KERNEL, proto);
+	if (!sk)
+		goto out;
+	rc = 0;
+
+	sock->ops = ops;
+
+	sock_init_data(sock, sk);
+	/* FIXME: sk->sk_destruct */
?
Oh... I nearly forgot about this. When writing this code, I examined
several existing address families. Usually (but not always) the sk_destruct
callback will purge sk_receive_queue and sk_write_queue. However I
didn't understand why and in which case should these queues (or others)
be purged. Could please one clarify this?
quoted
...

+static void af_ieee802154_remove(void)
Could be __exit, althugh __exit doesn't do much (it used to be
implemented on UML and might still be).
Added. BTW: I thought, that __exit functions aren't added to (or are
stripped from) the final vmlinux image. Am I wrong?
quoted

+static inline struct dgram_sock *dgram_sk(const struct sock *sk)
+{
+	return (struct dgram_sock *)sk;
Better to use container_of() - it's clearer and doesn't assume that
dgram_sock.sk is the first member.
Fixed.
quoted
+}

...

+static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len)
+{
+	struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr;
sigh, more casting.  Often these things can be done in ways which are
nicer to the C type system.
Unfortunately sockaddr things can't be done in a more clean way IMO.
quoted
+	struct dgram_sock *ro = dgram_sk(sk);
+	int err = 0;
+	struct net_device *dev;
+
+	ro->bound = 0;
+
quoted
...

+struct proto ieee802154_dgram_prot = {
I suspect this could/should be const.
No. proto_register changes the passed protocol struct during
registration.
quoted
+	.name		= "IEEE-802.15.4-MAC",
+	.owner		= THIS_MODULE,
+	.obj_size	= sizeof(struct dgram_sock),
+	.init		= dgram_init,
+	.close		= dgram_close,
+	.bind		= dgram_bind,
+	.sendmsg	= dgram_sendmsg,
+	.recvmsg	= dgram_recvmsg,
+	.hash		= dgram_hash,
+	.unhash		= dgram_unhash,
+	.connect	= dgram_connect,
+	.disconnect	= dgram_disconnect,
+	.ioctl		= dgram_ioctl,
+};
+
-- 
With best wishes
Dmitry
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help