aboutsummaryrefslogtreecommitdiffstats
path: root/net/atm/addr.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/atm/addr.c')
-rw-r--r--net/atm/addr.c55
1 files changed, 41 insertions, 14 deletions
diff --git a/net/atm/addr.c b/net/atm/addr.c
index 1c8867f7f54a..3060fd0ba4b9 100644
--- a/net/atm/addr.c
+++ b/net/atm/addr.c
@@ -44,29 +44,43 @@ static void notify_sigd(struct atm_dev *dev)
44 sigd_enq(NULL, as_itf_notify, NULL, &pvc, NULL); 44 sigd_enq(NULL, as_itf_notify, NULL, &pvc, NULL);
45} 45}
46 46
47void atm_reset_addr(struct atm_dev *dev) 47void atm_reset_addr(struct atm_dev *dev, enum atm_addr_type_t atype)
48{ 48{
49 unsigned long flags; 49 unsigned long flags;
50 struct atm_dev_addr *this, *p; 50 struct atm_dev_addr *this, *p;
51 struct list_head *head;
51 52
52 spin_lock_irqsave(&dev->lock, flags); 53 spin_lock_irqsave(&dev->lock, flags);
53 list_for_each_entry_safe(this, p, &dev->local, entry) 54 if (atype == ATM_ADDR_LECS)
54 kfree(this); 55 head = &dev->lecs;
56 else
57 head = &dev->local;
58 list_for_each_entry_safe(this, p, head, entry) {
59 list_del(&this->entry);
60 kfree(this);
61 }
55 spin_unlock_irqrestore(&dev->lock, flags); 62 spin_unlock_irqrestore(&dev->lock, flags);
56 notify_sigd(dev); 63 if (head == &dev->local)
64 notify_sigd(dev);
57} 65}
58 66
59int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr) 67int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
68 enum atm_addr_type_t atype)
60{ 69{
61 unsigned long flags; 70 unsigned long flags;
62 struct atm_dev_addr *this; 71 struct atm_dev_addr *this;
72 struct list_head *head;
63 int error; 73 int error;
64 74
65 error = check_addr(addr); 75 error = check_addr(addr);
66 if (error) 76 if (error)
67 return error; 77 return error;
68 spin_lock_irqsave(&dev->lock, flags); 78 spin_lock_irqsave(&dev->lock, flags);
69 list_for_each_entry(this, &dev->local, entry) { 79 if (atype == ATM_ADDR_LECS)
80 head = &dev->lecs;
81 else
82 head = &dev->local;
83 list_for_each_entry(this, head, entry) {
70 if (identical(&this->addr, addr)) { 84 if (identical(&this->addr, addr)) {
71 spin_unlock_irqrestore(&dev->lock, flags); 85 spin_unlock_irqrestore(&dev->lock, flags);
72 return -EEXIST; 86 return -EEXIST;
@@ -78,28 +92,36 @@ int atm_add_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr)
78 return -ENOMEM; 92 return -ENOMEM;
79 } 93 }
80 this->addr = *addr; 94 this->addr = *addr;
81 list_add(&this->entry, &dev->local); 95 list_add(&this->entry, head);
82 spin_unlock_irqrestore(&dev->lock, flags); 96 spin_unlock_irqrestore(&dev->lock, flags);
83 notify_sigd(dev); 97 if (head == &dev->local)
98 notify_sigd(dev);
84 return 0; 99 return 0;
85} 100}
86 101
87int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr) 102int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr,
103 enum atm_addr_type_t atype)
88{ 104{
89 unsigned long flags; 105 unsigned long flags;
90 struct atm_dev_addr *this; 106 struct atm_dev_addr *this;
107 struct list_head *head;
91 int error; 108 int error;
92 109
93 error = check_addr(addr); 110 error = check_addr(addr);
94 if (error) 111 if (error)
95 return error; 112 return error;
96 spin_lock_irqsave(&dev->lock, flags); 113 spin_lock_irqsave(&dev->lock, flags);
97 list_for_each_entry(this, &dev->local, entry) { 114 if (atype == ATM_ADDR_LECS)
115 head = &dev->lecs;
116 else
117 head = &dev->local;
118 list_for_each_entry(this, head, entry) {
98 if (identical(&this->addr, addr)) { 119 if (identical(&this->addr, addr)) {
99 list_del(&this->entry); 120 list_del(&this->entry);
100 spin_unlock_irqrestore(&dev->lock, flags); 121 spin_unlock_irqrestore(&dev->lock, flags);
101 kfree(this); 122 kfree(this);
102 notify_sigd(dev); 123 if (head == &dev->local)
124 notify_sigd(dev);
103 return 0; 125 return 0;
104 } 126 }
105 } 127 }
@@ -108,22 +130,27 @@ int atm_del_addr(struct atm_dev *dev, struct sockaddr_atmsvc *addr)
108} 130}
109 131
110int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user * buf, 132int atm_get_addr(struct atm_dev *dev, struct sockaddr_atmsvc __user * buf,
111 size_t size) 133 size_t size, enum atm_addr_type_t atype)
112{ 134{
113 unsigned long flags; 135 unsigned long flags;
114 struct atm_dev_addr *this; 136 struct atm_dev_addr *this;
137 struct list_head *head;
115 int total = 0, error; 138 int total = 0, error;
116 struct sockaddr_atmsvc *tmp_buf, *tmp_bufp; 139 struct sockaddr_atmsvc *tmp_buf, *tmp_bufp;
117 140
118 spin_lock_irqsave(&dev->lock, flags); 141 spin_lock_irqsave(&dev->lock, flags);
119 list_for_each_entry(this, &dev->local, entry) 142 if (atype == ATM_ADDR_LECS)
143 head = &dev->lecs;
144 else
145 head = &dev->local;
146 list_for_each_entry(this, head, entry)
120 total += sizeof(struct sockaddr_atmsvc); 147 total += sizeof(struct sockaddr_atmsvc);
121 tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC); 148 tmp_buf = tmp_bufp = kmalloc(total, GFP_ATOMIC);
122 if (!tmp_buf) { 149 if (!tmp_buf) {
123 spin_unlock_irqrestore(&dev->lock, flags); 150 spin_unlock_irqrestore(&dev->lock, flags);
124 return -ENOMEM; 151 return -ENOMEM;
125 } 152 }
126 list_for_each_entry(this, &dev->local, entry) 153 list_for_each_entry(this, head, entry)
127 memcpy(tmp_bufp++, &this->addr, sizeof(struct sockaddr_atmsvc)); 154 memcpy(tmp_bufp++, &this->addr, sizeof(struct sockaddr_atmsvc));
128 spin_unlock_irqrestore(&dev->lock, flags); 155 spin_unlock_irqrestore(&dev->lock, flags);
129 error = total > size ? -E2BIG : total; 156 error = total > size ? -E2BIG : total;