0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #define pr_fmt(fmt) KBUILD_MODNAME ":%s: " fmt, __func__
0012
0013 #include <linux/ctype.h>
0014 #include <linux/string.h>
0015 #include <linux/atmdev.h>
0016 #include <linux/sonet.h>
0017 #include <linux/kernel.h> /* for barrier */
0018 #include <linux/module.h>
0019 #include <linux/bitops.h>
0020 #include <linux/capability.h>
0021 #include <linux/delay.h>
0022 #include <linux/mutex.h>
0023 #include <linux/slab.h>
0024
0025 #include <net/sock.h> /* for struct sock */
0026
0027 #include "common.h"
0028 #include "resources.h"
0029 #include "addr.h"
0030
0031
0032 LIST_HEAD(atm_devs);
0033 DEFINE_MUTEX(atm_dev_mutex);
0034
0035 static struct atm_dev *__alloc_atm_dev(const char *type)
0036 {
0037 struct atm_dev *dev;
0038
0039 dev = kzalloc(sizeof(*dev), GFP_KERNEL);
0040 if (!dev)
0041 return NULL;
0042 dev->type = type;
0043 dev->signal = ATM_PHY_SIG_UNKNOWN;
0044 dev->link_rate = ATM_OC3_PCR;
0045 spin_lock_init(&dev->lock);
0046 INIT_LIST_HEAD(&dev->local);
0047 INIT_LIST_HEAD(&dev->lecs);
0048
0049 return dev;
0050 }
0051
0052 static struct atm_dev *__atm_dev_lookup(int number)
0053 {
0054 struct atm_dev *dev;
0055
0056 list_for_each_entry(dev, &atm_devs, dev_list) {
0057 if (dev->number == number) {
0058 atm_dev_hold(dev);
0059 return dev;
0060 }
0061 }
0062 return NULL;
0063 }
0064
0065 struct atm_dev *atm_dev_lookup(int number)
0066 {
0067 struct atm_dev *dev;
0068
0069 mutex_lock(&atm_dev_mutex);
0070 dev = __atm_dev_lookup(number);
0071 mutex_unlock(&atm_dev_mutex);
0072 return dev;
0073 }
0074 EXPORT_SYMBOL(atm_dev_lookup);
0075
0076 struct atm_dev *atm_dev_register(const char *type, struct device *parent,
0077 const struct atmdev_ops *ops, int number,
0078 unsigned long *flags)
0079 {
0080 struct atm_dev *dev, *inuse;
0081
0082 dev = __alloc_atm_dev(type);
0083 if (!dev) {
0084 pr_err("no space for dev %s\n", type);
0085 return NULL;
0086 }
0087 mutex_lock(&atm_dev_mutex);
0088 if (number != -1) {
0089 inuse = __atm_dev_lookup(number);
0090 if (inuse) {
0091 atm_dev_put(inuse);
0092 mutex_unlock(&atm_dev_mutex);
0093 kfree(dev);
0094 return NULL;
0095 }
0096 dev->number = number;
0097 } else {
0098 dev->number = 0;
0099 while ((inuse = __atm_dev_lookup(dev->number))) {
0100 atm_dev_put(inuse);
0101 dev->number++;
0102 }
0103 }
0104
0105 dev->ops = ops;
0106 if (flags)
0107 dev->flags = *flags;
0108 else
0109 memset(&dev->flags, 0, sizeof(dev->flags));
0110 memset(&dev->stats, 0, sizeof(dev->stats));
0111 refcount_set(&dev->refcnt, 1);
0112
0113 if (atm_proc_dev_register(dev) < 0) {
0114 pr_err("atm_proc_dev_register failed for dev %s\n", type);
0115 goto out_fail;
0116 }
0117
0118 if (atm_register_sysfs(dev, parent) < 0) {
0119 pr_err("atm_register_sysfs failed for dev %s\n", type);
0120 atm_proc_dev_deregister(dev);
0121 goto out_fail;
0122 }
0123
0124 list_add_tail(&dev->dev_list, &atm_devs);
0125
0126 out:
0127 mutex_unlock(&atm_dev_mutex);
0128 return dev;
0129
0130 out_fail:
0131 kfree(dev);
0132 dev = NULL;
0133 goto out;
0134 }
0135 EXPORT_SYMBOL(atm_dev_register);
0136
0137 void atm_dev_deregister(struct atm_dev *dev)
0138 {
0139 BUG_ON(test_bit(ATM_DF_REMOVED, &dev->flags));
0140 set_bit(ATM_DF_REMOVED, &dev->flags);
0141
0142
0143
0144
0145
0146
0147 mutex_lock(&atm_dev_mutex);
0148 list_del(&dev->dev_list);
0149 mutex_unlock(&atm_dev_mutex);
0150
0151 atm_dev_release_vccs(dev);
0152 atm_unregister_sysfs(dev);
0153 atm_proc_dev_deregister(dev);
0154
0155 atm_dev_put(dev);
0156 }
0157 EXPORT_SYMBOL(atm_dev_deregister);
0158
0159 static void copy_aal_stats(struct k_atm_aal_stats *from,
0160 struct atm_aal_stats *to)
0161 {
0162 #define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
0163 __AAL_STAT_ITEMS
0164 #undef __HANDLE_ITEM
0165 }
0166
0167 static void subtract_aal_stats(struct k_atm_aal_stats *from,
0168 struct atm_aal_stats *to)
0169 {
0170 #define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
0171 __AAL_STAT_ITEMS
0172 #undef __HANDLE_ITEM
0173 }
0174
0175 static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats __user *arg,
0176 int zero)
0177 {
0178 struct atm_dev_stats tmp;
0179 int error = 0;
0180
0181 copy_aal_stats(&dev->stats.aal0, &tmp.aal0);
0182 copy_aal_stats(&dev->stats.aal34, &tmp.aal34);
0183 copy_aal_stats(&dev->stats.aal5, &tmp.aal5);
0184 if (arg)
0185 error = copy_to_user(arg, &tmp, sizeof(tmp));
0186 if (zero && !error) {
0187 subtract_aal_stats(&dev->stats.aal0, &tmp.aal0);
0188 subtract_aal_stats(&dev->stats.aal34, &tmp.aal34);
0189 subtract_aal_stats(&dev->stats.aal5, &tmp.aal5);
0190 }
0191 return error ? -EFAULT : 0;
0192 }
0193
0194 int atm_getnames(void __user *buf, int __user *iobuf_len)
0195 {
0196 int error, len, size = 0;
0197 struct atm_dev *dev;
0198 struct list_head *p;
0199 int *tmp_buf, *tmp_p;
0200
0201 if (get_user(len, iobuf_len))
0202 return -EFAULT;
0203 mutex_lock(&atm_dev_mutex);
0204 list_for_each(p, &atm_devs)
0205 size += sizeof(int);
0206 if (size > len) {
0207 mutex_unlock(&atm_dev_mutex);
0208 return -E2BIG;
0209 }
0210 tmp_buf = kmalloc(size, GFP_ATOMIC);
0211 if (!tmp_buf) {
0212 mutex_unlock(&atm_dev_mutex);
0213 return -ENOMEM;
0214 }
0215 tmp_p = tmp_buf;
0216 list_for_each_entry(dev, &atm_devs, dev_list) {
0217 *tmp_p++ = dev->number;
0218 }
0219 mutex_unlock(&atm_dev_mutex);
0220 error = ((copy_to_user(buf, tmp_buf, size)) ||
0221 put_user(size, iobuf_len))
0222 ? -EFAULT : 0;
0223 kfree(tmp_buf);
0224 return error;
0225 }
0226
0227 int atm_dev_ioctl(unsigned int cmd, void __user *buf, int __user *sioc_len,
0228 int number, int compat)
0229 {
0230 int error, len, size = 0;
0231 struct atm_dev *dev;
0232
0233 if (get_user(len, sioc_len))
0234 return -EFAULT;
0235
0236 dev = try_then_request_module(atm_dev_lookup(number), "atm-device-%d",
0237 number);
0238 if (!dev)
0239 return -ENODEV;
0240
0241 switch (cmd) {
0242 case ATM_GETTYPE:
0243 size = strlen(dev->type) + 1;
0244 if (copy_to_user(buf, dev->type, size)) {
0245 error = -EFAULT;
0246 goto done;
0247 }
0248 break;
0249 case ATM_GETESI:
0250 size = ESI_LEN;
0251 if (copy_to_user(buf, dev->esi, size)) {
0252 error = -EFAULT;
0253 goto done;
0254 }
0255 break;
0256 case ATM_SETESI:
0257 {
0258 int i;
0259
0260 for (i = 0; i < ESI_LEN; i++)
0261 if (dev->esi[i]) {
0262 error = -EEXIST;
0263 goto done;
0264 }
0265 }
0266 fallthrough;
0267 case ATM_SETESIF:
0268 {
0269 unsigned char esi[ESI_LEN];
0270
0271 if (!capable(CAP_NET_ADMIN)) {
0272 error = -EPERM;
0273 goto done;
0274 }
0275 if (copy_from_user(esi, buf, ESI_LEN)) {
0276 error = -EFAULT;
0277 goto done;
0278 }
0279 memcpy(dev->esi, esi, ESI_LEN);
0280 error = ESI_LEN;
0281 goto done;
0282 }
0283 case ATM_GETSTATZ:
0284 if (!capable(CAP_NET_ADMIN)) {
0285 error = -EPERM;
0286 goto done;
0287 }
0288 fallthrough;
0289 case ATM_GETSTAT:
0290 size = sizeof(struct atm_dev_stats);
0291 error = fetch_stats(dev, buf, cmd == ATM_GETSTATZ);
0292 if (error)
0293 goto done;
0294 break;
0295 case ATM_GETCIRANGE:
0296 size = sizeof(struct atm_cirange);
0297 if (copy_to_user(buf, &dev->ci_range, size)) {
0298 error = -EFAULT;
0299 goto done;
0300 }
0301 break;
0302 case ATM_GETLINKRATE:
0303 size = sizeof(int);
0304 if (copy_to_user(buf, &dev->link_rate, size)) {
0305 error = -EFAULT;
0306 goto done;
0307 }
0308 break;
0309 case ATM_RSTADDR:
0310 if (!capable(CAP_NET_ADMIN)) {
0311 error = -EPERM;
0312 goto done;
0313 }
0314 atm_reset_addr(dev, ATM_ADDR_LOCAL);
0315 break;
0316 case ATM_ADDADDR:
0317 case ATM_DELADDR:
0318 case ATM_ADDLECSADDR:
0319 case ATM_DELLECSADDR:
0320 {
0321 struct sockaddr_atmsvc addr;
0322
0323 if (!capable(CAP_NET_ADMIN)) {
0324 error = -EPERM;
0325 goto done;
0326 }
0327
0328 if (copy_from_user(&addr, buf, sizeof(addr))) {
0329 error = -EFAULT;
0330 goto done;
0331 }
0332 if (cmd == ATM_ADDADDR || cmd == ATM_ADDLECSADDR)
0333 error = atm_add_addr(dev, &addr,
0334 (cmd == ATM_ADDADDR ?
0335 ATM_ADDR_LOCAL : ATM_ADDR_LECS));
0336 else
0337 error = atm_del_addr(dev, &addr,
0338 (cmd == ATM_DELADDR ?
0339 ATM_ADDR_LOCAL : ATM_ADDR_LECS));
0340 goto done;
0341 }
0342 case ATM_GETADDR:
0343 case ATM_GETLECSADDR:
0344 error = atm_get_addr(dev, buf, len,
0345 (cmd == ATM_GETADDR ?
0346 ATM_ADDR_LOCAL : ATM_ADDR_LECS));
0347 if (error < 0)
0348 goto done;
0349 size = error;
0350
0351
0352 error = put_user(size, sioc_len) ? -EFAULT : 0;
0353 goto done;
0354 case ATM_SETLOOP:
0355 if (__ATM_LM_XTRMT((int) (unsigned long) buf) &&
0356 __ATM_LM_XTLOC((int) (unsigned long) buf) >
0357 __ATM_LM_XTRMT((int) (unsigned long) buf)) {
0358 error = -EINVAL;
0359 goto done;
0360 }
0361 fallthrough;
0362 case ATM_SETCIRANGE:
0363 case SONET_GETSTATZ:
0364 case SONET_SETDIAG:
0365 case SONET_CLRDIAG:
0366 case SONET_SETFRAMING:
0367 if (!capable(CAP_NET_ADMIN)) {
0368 error = -EPERM;
0369 goto done;
0370 }
0371 fallthrough;
0372 default:
0373 if (IS_ENABLED(CONFIG_COMPAT) && compat) {
0374 #ifdef CONFIG_COMPAT
0375 if (!dev->ops->compat_ioctl) {
0376 error = -EINVAL;
0377 goto done;
0378 }
0379 size = dev->ops->compat_ioctl(dev, cmd, buf);
0380 #endif
0381 } else {
0382 if (!dev->ops->ioctl) {
0383 error = -EINVAL;
0384 goto done;
0385 }
0386 size = dev->ops->ioctl(dev, cmd, buf);
0387 }
0388 if (size < 0) {
0389 error = (size == -ENOIOCTLCMD ? -ENOTTY : size);
0390 goto done;
0391 }
0392 }
0393
0394 if (size)
0395 error = put_user(size, sioc_len) ? -EFAULT : 0;
0396 else
0397 error = 0;
0398 done:
0399 atm_dev_put(dev);
0400 return error;
0401 }
0402
0403 void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
0404 {
0405 mutex_lock(&atm_dev_mutex);
0406 return seq_list_start_head(&atm_devs, *pos);
0407 }
0408
0409 void atm_dev_seq_stop(struct seq_file *seq, void *v)
0410 {
0411 mutex_unlock(&atm_dev_mutex);
0412 }
0413
0414 void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
0415 {
0416 return seq_list_next(v, &atm_devs, pos);
0417 }