/* net/atm/addr.c - Local ATM address registry */

/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */

#include <linux/atm.h>
#include <linux/atmdev.h>
#include <asm/uaccess.h>

#include "signaling.h"
#include "addr.h"

static int check_addr(struct sockaddr_atmsvc *addr)
{
	int i;

	if (addr->sas_family != AF_ATMSVC)
		return -EAFNOSUPPORT;
	if (!*addr->sas_addr.pub)
		return *addr->sas_addr.prv ? 0 : -EINVAL;
	for (i = 1; i < ATM_E164_LEN + 1; i++)	/* make sure it's \0-terminated */
		if (!addr->sas_addr.pub[i])
			return 0;
	return -EINVAL;
}

static int identical(struct sockaddr_atmsvc *a, struct sockaddr_atmsvc *b)
{
	if (*a->sas_addr.prv)
		if (memcmp(a->sas_addr.prv, b->sas_addr.prv, ATM_ESA_LEN))
			return 0;
	if (!*a->sas_addr.pub)
		return !*b->sas_addr.pub;
	if (!*b->sas_addr.pub)
		return 0;
	return !strcmp(a->sas_addr.pub, b->sas_addr.pub);
}

static void notify_sigd(struct atm_dev *dev)
{
	struct sockaddr_atmpvc pvc;

	pvc.sap_addr.itf = dev->number;
	sigd_enq(NULL, as_itf_notify, NULL, &pvc, NULL);
}

void atm_reset_addr(struct atm_dev *dev, enum atm_addr_type_t atype)
{
	unsigned long flags;
	struct atm_dev_addr *this, *p;
	struct list_head *head;

	spin_lock_irqsave(&dev->lock, flags);
	if (atype == ATM_ADDR_LECS)
		head = &dev->lecs;
	else
		head = &dev->local;
	list_for_each_entry_safe(this, p, head, entry) {
		list_del(&this->entry);
		kfree(this);
	}
	spin_unlock_irqrestore(&dev->lock, flags);
	if (head == &dev->local)
		notify_sigd(dev);
}

int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
		 enum atm_addr_type_t atype)
{
	unsigned long flags;
	struct atm_dev_addr *this;
	struct list_head *head;
	int error;

	error = check_addr(addr);
	if (error)
		return error;
	spin_lock_irqsave(&dev->lock, flags);
	if (atype == ATM_ADDR_LECS)
		head = &dev->lecs;
	else
		head = &dev->local;
	list_for_each_entry(this, head, entry) {
		if (identical(&this->addr, addr)) {
			spin_unlock_irqrestore(&dev->lock, flags);
			return -EEXIST;
		}
	}
	this = kmalloc(sizeof(struct atm_dev_addr), GFP_ATOMIC);
	if (!this) {
		spin_unlock_irqrestore(&dev->lock, flags);
		return -ENOMEM;
	}
	this->addr = *addr;
	list_add(&this->entry, head);
	spin_unlock_irqrestore(&dev->lock, flags);
	if (head == &dev->local)
		notify_sigd(dev);
	return 0;
}

int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
		 enum atm_addr_type_t atype)
{
	unsigned long flags;
	struct atm_dev_addr *this;
	struct list_head *head;
	int error;

	error = check_addr(addr);
	if (error)
		return error;
	spin_lock_irqsave(&dev->lock, flags);
	if (atype == ATM_ADDR_LECS)
		head = &dev->lecs;
	else
		head = &dev->local;
	list_for_each_entry(this, head, entry) {
		if (identical(&this->addr, addr)) {
			list_del(&this->entry);
			spin_unlock_irqrestore(&dev->lock, flags);
			kfree(this);
			if (head == &dev->local)
				notify_sigd(dev);
			return 0;
		}
	}
	spin_unlock_irqrestore(&dev->lock, flags);
	return -ENOENT;
}

int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user * buf,
		 size_t size, enum atm_addr_type_t atype)
{
	unsigned long flags;
	struct atm_dev_addr *this;
	struct list_head *head;
	int total = 0, error;
	struct sockaddr_atmsvc *tmp_buf, *tmp_bufp;

	spin_lock_irqsave(&dev->lock, flags);
	if (atype == ATM_ADDR_LECS)
		head = &dev->lecs;
	else
		head = &dev->local;
	list_for_each_entry(this, head, entry)
	    total += sizeof(struct sockaddr_atmsvc);
	tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC);
	if (!tmp_buf) {
		spin_unlock_irqrestore(&dev->lock, flags);
		return -ENOMEM;
	}
	list_for_each_entry(this, head, entry)
	    memcpy(tmp_bufp++, &this->addr, sizeof(struct sockaddr_atmsvc));
	spin_unlock_irqrestore(&dev->lock, flags);
	error = total > size ? -E2BIG : total;
	if (copy_to_user(buf, tmp_buf, total < size ? total : size))
		error = -EFAULT;
	kfree(tmp_buf);
	return error;
}
