OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [atm/] [addr.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* net/atm/addr.c - Local ATM address registry */
2
 
3
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */
4
 
5
 
6
#include <linux/atm.h>
7
#include <linux/atmdev.h>
8
#include <linux/sched.h>
9
#include <asm/uaccess.h>
10
 
11
#include "signaling.h"
12
#include "addr.h"
13
 
14
 
15
static int check_addr(struct sockaddr_atmsvc *addr)
16
{
17
        int i;
18
 
19
        if (addr->sas_family != AF_ATMSVC) return -EAFNOSUPPORT;
20
        if (!*addr->sas_addr.pub)
21
                return *addr->sas_addr.prv ? 0 : -EINVAL;
22
        for (i = 1; i < ATM_E164_LEN+1; i++) /* make sure it's \0-terminated */
23
                if (!addr->sas_addr.pub[i]) return 0;
24
        return -EINVAL;
25
}
26
 
27
 
28
static int identical(struct sockaddr_atmsvc *a,struct sockaddr_atmsvc *b)
29
{
30
        if (*a->sas_addr.prv)
31
                if (memcmp(a->sas_addr.prv,b->sas_addr.prv,ATM_ESA_LEN))
32
                        return 0;
33
        if (!*a->sas_addr.pub) return !*b->sas_addr.pub;
34
        if (!*b->sas_addr.pub) return 0;
35
        return !strcmp(a->sas_addr.pub,b->sas_addr.pub);
36
}
37
 
38
 
39
static void notify_sigd(struct atm_dev *dev)
40
{
41
        struct sockaddr_atmpvc pvc;
42
 
43
        pvc.sap_addr.itf = dev->number;
44
        sigd_enq(NULL,as_itf_notify,NULL,&pvc,NULL);
45
}
46
 
47
 
48
void atm_reset_addr(struct atm_dev *dev)
49
{
50
        unsigned long flags;
51
        struct atm_dev_addr *this;
52
 
53
        spin_lock_irqsave(&dev->lock, flags);
54
        while (dev->local) {
55
                this = dev->local;
56
                dev->local = this->next;
57
                kfree(this);
58
        }
59
        spin_unlock_irqrestore(&dev->lock, flags);
60
        notify_sigd(dev);
61
}
62
 
63
 
64
int atm_add_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
65
{
66
        unsigned long flags;
67
        struct atm_dev_addr **walk;
68
        int error;
69
 
70
        error = check_addr(addr);
71
        if (error)
72
                return error;
73
        spin_lock_irqsave(&dev->lock, flags);
74
        for (walk = &dev->local; *walk; walk = &(*walk)->next)
75
                if (identical(&(*walk)->addr,addr)) {
76
                        spin_unlock_irqrestore(&dev->lock, flags);
77
                        return -EEXIST;
78
                }
79
        *walk = kmalloc(sizeof(struct atm_dev_addr), GFP_ATOMIC);
80
        if (!*walk) {
81
                spin_unlock_irqrestore(&dev->lock, flags);
82
                return -ENOMEM;
83
        }
84
        (*walk)->addr = *addr;
85
        (*walk)->next = NULL;
86
        spin_unlock_irqrestore(&dev->lock, flags);
87
        notify_sigd(dev);
88
        return 0;
89
}
90
 
91
 
92
int atm_del_addr(struct atm_dev *dev,struct sockaddr_atmsvc *addr)
93
{
94
        unsigned long flags;
95
        struct atm_dev_addr **walk,*this;
96
        int error;
97
 
98
        error = check_addr(addr);
99
        if (error)
100
                return error;
101
        spin_lock_irqsave(&dev->lock, flags);
102
        for (walk = &dev->local; *walk; walk = &(*walk)->next)
103
                if (identical(&(*walk)->addr,addr)) break;
104
        if (!*walk) {
105
                spin_unlock_irqrestore(&dev->lock, flags);
106
                return -ENOENT;
107
        }
108
        this = *walk;
109
        *walk = this->next;
110
        kfree(this);
111
        spin_unlock_irqrestore(&dev->lock, flags);
112
        notify_sigd(dev);
113
        return 0;
114
}
115
 
116
 
117
int atm_get_addr(struct atm_dev *dev,struct sockaddr_atmsvc *u_buf,int size)
118
{
119
        unsigned long flags;
120
        struct atm_dev_addr *walk;
121
        int total = 0, error;
122
        struct sockaddr_atmsvc *tmp_buf, *tmp_bufp;
123
 
124
 
125
        spin_lock_irqsave(&dev->lock, flags);
126
        for (walk = dev->local; walk; walk = walk->next)
127
                total += sizeof(struct sockaddr_atmsvc);
128
        tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC);
129
        if (!tmp_buf) {
130
                spin_unlock_irqrestore(&dev->lock, flags);
131
                return -ENOMEM;
132
        }
133
        for (walk = dev->local; walk; walk = walk->next)
134
                memcpy(tmp_bufp++, &walk->addr, sizeof(struct sockaddr_atmsvc));
135
        spin_unlock_irqrestore(&dev->lock, flags);
136
        error = total > size ? -E2BIG : total;
137
        if (copy_to_user(u_buf, tmp_buf, total < size ? total : size))
138
                error = -EFAULT;
139
        kfree(tmp_buf);
140
        return error;
141
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.