All of lore.kernel.org
 help / color / mirror / Atom feed
From: Arnaldo Carvalho de Melo <acme@redhat.com>
To: "Rémi Denis-Courmont" <remi.denis-courmont@nokia.com>
Cc: netdev@vger.kernel.org
Subject: Re: [PATCH 05/14] Phonet: network device and address handling
Date: Tue, 16 Sep 2008 13:41:26 -0300	[thread overview]
Message-ID: <20080916164126.GI8702@ghostprotocols.net> (raw)
In-Reply-To: <1221577694-4513-5-git-send-email-remi.denis-courmont@nokia.com>

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

  reply	other threads:[~2008-09-16 16:50 UTC|newest]

Thread overview: 41+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

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

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

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

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

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

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

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