📄 proc.c
字号:
"AAL(TX,err,RX,err,drop) ...\n"); } left = pos-1; for (dev = atm_devs; dev && left; dev = dev->next) left--; if (!dev) return 0; dev_info(dev,buf); return strlen(buf);}/* * FIXME: it isn't safe to walk the VCC list without turning off interrupts. * What is really needed is some lock on the devices. Ditto for ATMARP. */static int atm_pvc_info(loff_t pos,char *buf){ struct atm_dev *dev; struct atm_vcc *vcc; int left; if (!pos) { return sprintf(buf,"Itf VPI VCI AAL RX(PCR,Class) " "TX(PCR,Class)\n"); } left = pos-1; for (dev = atm_devs; dev; dev = dev->next) for (vcc = dev->vccs; vcc; vcc = vcc->next) if (vcc->family == PF_ATMPVC && vcc->dev && !left--) { pvc_info(vcc,buf); return strlen(buf); } return 0;}static int atm_vc_info(loff_t pos,char *buf){ struct atm_dev *dev; struct atm_vcc *vcc; int left; if (!pos) return sprintf(buf,sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s", "Address"," Itf VPI VCI Fam Flags Reply Send buffer" " Recv buffer\n"); left = pos-1; for (dev = atm_devs; dev; dev = dev->next) for (vcc = dev->vccs; vcc; vcc = vcc->next) if (!left--) { vc_info(vcc,buf); return strlen(buf); } for (vcc = nodev_vccs; vcc; vcc = vcc->next) if (!left--) { vc_info(vcc,buf); return strlen(buf); } return 0;}static int atm_svc_info(loff_t pos,char *buf){ struct atm_dev *dev; struct atm_vcc *vcc; int left; if (!pos) return sprintf(buf,"Itf VPI VCI State Remote\n"); left = pos-1; for (dev = atm_devs; dev; dev = dev->next) for (vcc = dev->vccs; vcc; vcc = vcc->next) if (vcc->family == PF_ATMSVC && !left--) { svc_info(vcc,buf); return strlen(buf); } for (vcc = nodev_vccs; vcc; vcc = vcc->next) if (vcc->family == PF_ATMSVC && !left--) { svc_info(vcc,buf); return strlen(buf); } return 0;}#ifdef CONFIG_ATM_CLIPstatic int atm_arp_info(loff_t pos,char *buf){ struct neighbour *n; int i,count; if (!pos) { return sprintf(buf,"IPitf TypeEncp Idle IP address " "ATM address\n"); } count = pos; read_lock_bh(&clip_tbl.lock); for (i = 0; i <= NEIGH_HASHMASK; i++) for (n = clip_tbl.hash_buckets[i]; n; n = n->next) { struct atmarp_entry *entry = NEIGH2ENTRY(n); struct clip_vcc *vcc; if (!entry->vccs) { if (--count) continue; atmarp_info(n->dev,entry,NULL,buf); read_unlock_bh(&clip_tbl.lock); return strlen(buf); } for (vcc = entry->vccs; vcc; vcc = vcc->next) { if (--count) continue; atmarp_info(n->dev,entry,vcc,buf); read_unlock_bh(&clip_tbl.lock); return strlen(buf); } } read_unlock_bh(&clip_tbl.lock); return 0;}#endif#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)static int atm_lec_info(loff_t pos,char *buf){ struct lec_priv *priv; struct lec_arp_table *entry; int i, count, d, e; struct net_device **dev_lec; if (!pos) { return sprintf(buf,"Itf MAC ATM destination" " Status Flags " "VPI/VCI Recv VPI/VCI\n"); } if (atm_lane_ops.get_lecs == NULL) return 0; /* the lane module is not there yet */ else dev_lec = atm_lane_ops.get_lecs(); count = pos; for(d=0;d<MAX_LEC_ITF;d++) { if (!dev_lec[d] || !(priv = (struct lec_priv *) dev_lec[d]->priv)) continue; for(i=0;i<LEC_ARP_TABLE_SIZE;i++) { entry = priv->lec_arp_tables[i]; for(;entry;entry=entry->next) { if (--count) continue; e=sprintf(buf,"%s ", dev_lec[d]->name); lec_info(entry,buf+e); return strlen(buf); } } for(entry=priv->lec_arp_empty_ones; entry; entry=entry->next) { if (--count) continue; e=sprintf(buf,"%s ",dev_lec[d]->name); lec_info(entry, buf+e); return strlen(buf); } for(entry=priv->lec_no_forward; entry; entry=entry->next) { if (--count) continue; e=sprintf(buf,"%s ",dev_lec[d]->name); lec_info(entry, buf+e); return strlen(buf); } for(entry=priv->mcast_fwds; entry; entry=entry->next) { if (--count) continue; e=sprintf(buf,"%s ",dev_lec[d]->name); lec_info(entry, buf+e); return strlen(buf); } } return 0;}#endifstatic ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count, loff_t *pos){ struct atm_dev *dev; unsigned long page; int length; if (count < 0) return -EINVAL; page = get_free_page(GFP_KERNEL); if (!page) return -ENOMEM; dev = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip) ->data; if (!dev->ops->proc_read) length = -EINVAL; else { length = dev->ops->proc_read(dev,pos,(char *) page); if (length > count) length = -EINVAL; } if (length >= 0) { if (copy_to_user(buf,(char *) page,length)) length = -EFAULT; (*pos)++; } free_page(page); return length;}static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count, loff_t *pos){ unsigned long page; int length; int (*info)(loff_t,char *); info = ((struct proc_dir_entry *) file->f_dentry->d_inode->u.generic_ip) ->data; if (count < 0) return -EINVAL; page = get_free_page(GFP_KERNEL); if (!page) return -ENOMEM; length = (*info)(*pos,(char *) page); if (length > count) length = -EINVAL; if (length >= 0) { if (copy_to_user(buf,(char *) page,length)) length = -EFAULT; (*pos)++; } free_page(page); return length;}struct proc_dir_entry *atm_proc_root;EXPORT_SYMBOL(atm_proc_root);int atm_proc_dev_register(struct atm_dev *dev){ int digits,num; int error; error = -ENOMEM; digits = 0; for (num = dev->number; num; num /= 10) digits++; if (!digits) digits++; dev->proc_name = kmalloc(strlen(dev->type)+digits+2,GFP_KERNEL); if (!dev->proc_name) goto fail1; sprintf(dev->proc_name,"%s:%d",dev->type, dev->number); dev->proc_entry = create_proc_entry(dev->proc_name, 0, atm_proc_root); if (!dev->proc_entry) goto fail0; dev->proc_entry->data = dev; dev->proc_entry->proc_fops = &proc_dev_atm_operations; dev->proc_entry->owner = THIS_MODULE; return 0; kfree(dev->proc_entry);fail0: kfree(dev->proc_name);fail1: return error;}void atm_proc_dev_deregister(struct atm_dev *dev){ remove_proc_entry(dev->proc_name, atm_proc_root); kfree(dev->proc_name);}#define CREATE_ENTRY(name) \ name = create_proc_entry(#name,0,atm_proc_root); \ if (!name) goto cleanup; \ name->data = atm_##name##_info; \ name->proc_fops = &proc_spec_atm_operations; \ name->owner = THIS_MODULEint __init atm_proc_init(void){ struct proc_dir_entry *devices = NULL,*pvc = NULL,*svc = NULL; struct proc_dir_entry *arp = NULL,*lec = NULL,*vc = NULL; atm_proc_root = proc_mkdir("net/atm",NULL); if (!atm_proc_root) return -ENOMEM; CREATE_ENTRY(devices); CREATE_ENTRY(pvc); CREATE_ENTRY(svc); CREATE_ENTRY(vc);#ifdef CONFIG_ATM_CLIP CREATE_ENTRY(arp);#endif#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) CREATE_ENTRY(lec);#endif return 0;cleanup: if (devices) remove_proc_entry("devices",atm_proc_root); if (pvc) remove_proc_entry("pvc",atm_proc_root); if (svc) remove_proc_entry("svc",atm_proc_root); if (arp) remove_proc_entry("arp",atm_proc_root); if (lec) remove_proc_entry("lec",atm_proc_root); if (vc) remove_proc_entry("vc",atm_proc_root); remove_proc_entry("net/atm",NULL); return -ENOMEM;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -