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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [atm/] [mpoa_proc.c] - Diff between revs 1275 and 1765

Only display areas with differences | Details | Blame | View Log

Rev 1275 Rev 1765
#include <linux/config.h>
#include <linux/config.h>
 
 
#ifdef CONFIG_PROC_FS
#ifdef CONFIG_PROC_FS
#include <linux/errno.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/kernel.h>
#include <linux/string.h> 
#include <linux/string.h> 
#include <linux/mm.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <linux/proc_fs.h>
#include <linux/time.h>
#include <linux/time.h>
#include <asm/uaccess.h>
#include <asm/uaccess.h>
#include <linux/atmmpc.h>
#include <linux/atmmpc.h>
#include <linux/atm.h>
#include <linux/atm.h>
#include "mpc.h"
#include "mpc.h"
#include "mpoa_caches.h"
#include "mpoa_caches.h"
 
 
/*
/*
 * mpoa_proc.c: Implementation MPOA client's proc
 * mpoa_proc.c: Implementation MPOA client's proc
 * file system statistics
 * file system statistics
 */
 */
 
 
#if 1
#if 1
#define dprintk printk   /* debug */
#define dprintk printk   /* debug */
#else
#else
#define dprintk(format,args...)
#define dprintk(format,args...)
#endif
#endif
 
 
#define STAT_FILE_NAME "mpc"     /* Our statistic file's name */
#define STAT_FILE_NAME "mpc"     /* Our statistic file's name */
 
 
extern struct mpoa_client *mpcs;
extern struct mpoa_client *mpcs;
extern struct proc_dir_entry *atm_proc_root;  /* from proc.c. */
extern struct proc_dir_entry *atm_proc_root;  /* from proc.c. */
 
 
static ssize_t proc_mpc_read(struct file *file, char *buff,
static ssize_t proc_mpc_read(struct file *file, char *buff,
                             size_t count, loff_t *pos);
                             size_t count, loff_t *pos);
 
 
static ssize_t proc_mpc_write(struct file *file, const char *buff,
static ssize_t proc_mpc_write(struct file *file, const char *buff,
                              size_t nbytes, loff_t *ppos);
                              size_t nbytes, loff_t *ppos);
 
 
static int parse_qos(const char *buff, int len);
static int parse_qos(const char *buff, int len);
 
 
/*
/*
 *   Define allowed FILE OPERATIONS
 *   Define allowed FILE OPERATIONS
 */
 */
static struct file_operations mpc_file_operations = {
static struct file_operations mpc_file_operations = {
        read:           proc_mpc_read,
        read:           proc_mpc_read,
        write:          proc_mpc_write,
        write:          proc_mpc_write,
};
};
 
 
static int print_header(char *buff,struct mpoa_client *mpc){
static int print_header(char *buff,struct mpoa_client *mpc){
        if(mpc != NULL){
        if(mpc != NULL){
                return sprintf(buff,"\nInterface %d:\n\n",mpc->dev_num);
                return sprintf(buff,"\nInterface %d:\n\n",mpc->dev_num);
 
 
        }
        }
        return 0;
        return 0;
}
}
 
 
/*
/*
 * Returns the state of an ingress cache entry as a string
 * Returns the state of an ingress cache entry as a string
 */
 */
static const char *ingress_state_string(int state){
static const char *ingress_state_string(int state){
        switch(state) {
        switch(state) {
        case INGRESS_RESOLVING:
        case INGRESS_RESOLVING:
                return "resolving  ";
                return "resolving  ";
                break;
                break;
        case INGRESS_RESOLVED:
        case INGRESS_RESOLVED:
                return "resolved   ";
                return "resolved   ";
                break;
                break;
        case INGRESS_INVALID:
        case INGRESS_INVALID:
                return "invalid    ";
                return "invalid    ";
                break;
                break;
        case INGRESS_REFRESHING:
        case INGRESS_REFRESHING:
                return "refreshing ";
                return "refreshing ";
                break;
                break;
        default:
        default:
               return "";
               return "";
        }
        }
}
}
 
 
/*
/*
 * Returns the state of an egress cache entry as a string
 * Returns the state of an egress cache entry as a string
 */
 */
static const char *egress_state_string(int state){
static const char *egress_state_string(int state){
        switch(state) {
        switch(state) {
        case EGRESS_RESOLVED:
        case EGRESS_RESOLVED:
                return "resolved   ";
                return "resolved   ";
                break;
                break;
        case EGRESS_PURGE:
        case EGRESS_PURGE:
                return "purge      ";
                return "purge      ";
                break;
                break;
        case EGRESS_INVALID:
        case EGRESS_INVALID:
                return "invalid    ";
                return "invalid    ";
                break;
                break;
        default:
        default:
               return "";
               return "";
        }
        }
}
}
 
 
/*
/*
 * READING function - called when the /proc/atm/mpoa file is read from.
 * READING function - called when the /proc/atm/mpoa file is read from.
 */
 */
static ssize_t proc_mpc_read(struct file *file, char *buff,
static ssize_t proc_mpc_read(struct file *file, char *buff,
                             size_t count, loff_t *pos){
                             size_t count, loff_t *pos){
        unsigned long page = 0;
        unsigned long page = 0;
        unsigned char *temp;
        unsigned char *temp;
        int length = 0;
        int length = 0;
        int i = 0;
        int i = 0;
        struct mpoa_client *mpc = mpcs;
        struct mpoa_client *mpc = mpcs;
        in_cache_entry *in_entry;
        in_cache_entry *in_entry;
        eg_cache_entry *eg_entry;
        eg_cache_entry *eg_entry;
        struct timeval now;
        struct timeval now;
        unsigned char ip_string[16];
        unsigned char ip_string[16];
        if(count == 0)
        if(count == 0)
                return 0;
                return 0;
        page = get_free_page(GFP_KERNEL);
        page = get_free_page(GFP_KERNEL);
        if(!page)
        if(!page)
                return -ENOMEM;
                return -ENOMEM;
        atm_mpoa_disp_qos((char *)page, &length);
        atm_mpoa_disp_qos((char *)page, &length);
        while(mpc != NULL){
        while(mpc != NULL){
                length += print_header((char *)page + length, mpc);
                length += print_header((char *)page + length, mpc);
                length += sprintf((char *)page + length,"Ingress Entries:\nIP address      State      Holding time  Packets fwded  VPI  VCI\n");
                length += sprintf((char *)page + length,"Ingress Entries:\nIP address      State      Holding time  Packets fwded  VPI  VCI\n");
                in_entry = mpc->in_cache;
                in_entry = mpc->in_cache;
                do_gettimeofday(&now);
                do_gettimeofday(&now);
                while(in_entry != NULL){
                while(in_entry != NULL){
                        temp = (unsigned char *)&in_entry->ctrl_info.in_dst_ip;                        sprintf(ip_string,"%d.%d.%d.%d", temp[0], temp[1], temp[2], temp[3]);
                        temp = (unsigned char *)&in_entry->ctrl_info.in_dst_ip;                        sprintf(ip_string,"%d.%d.%d.%d", temp[0], temp[1], temp[2], temp[3]);
                        length += sprintf((char *)page + length,"%-16s%s%-14lu%-12u", ip_string, ingress_state_string(in_entry->entry_state), (in_entry->ctrl_info.holding_time-(now.tv_sec-in_entry->tv.tv_sec)), in_entry->packets_fwded);
                        length += sprintf((char *)page + length,"%-16s%s%-14lu%-12u", ip_string, ingress_state_string(in_entry->entry_state), (in_entry->ctrl_info.holding_time-(now.tv_sec-in_entry->tv.tv_sec)), in_entry->packets_fwded);
                        if(in_entry->shortcut)
                        if(in_entry->shortcut)
                                length += sprintf((char *)page + length,"   %-3d  %-3d",in_entry->shortcut->vpi,in_entry->shortcut->vci);
                                length += sprintf((char *)page + length,"   %-3d  %-3d",in_entry->shortcut->vpi,in_entry->shortcut->vci);
                        length += sprintf((char *)page + length,"\n");
                        length += sprintf((char *)page + length,"\n");
                        in_entry = in_entry->next;
                        in_entry = in_entry->next;
                }
                }
                length += sprintf((char *)page + length,"\n");
                length += sprintf((char *)page + length,"\n");
                eg_entry = mpc->eg_cache;
                eg_entry = mpc->eg_cache;
                length += sprintf((char *)page + length,"Egress Entries:\nIngress MPC ATM addr\nCache-id        State      Holding time  Packets recvd  Latest IP addr   VPI VCI\n");
                length += sprintf((char *)page + length,"Egress Entries:\nIngress MPC ATM addr\nCache-id        State      Holding time  Packets recvd  Latest IP addr   VPI VCI\n");
                while(eg_entry != NULL){
                while(eg_entry != NULL){
                  for(i=0;i<ATM_ESA_LEN;i++){
                  for(i=0;i<ATM_ESA_LEN;i++){
                          length += sprintf((char *)page + length,"%02x",eg_entry->ctrl_info.in_MPC_data_ATM_addr[i]);}
                          length += sprintf((char *)page + length,"%02x",eg_entry->ctrl_info.in_MPC_data_ATM_addr[i]);}
                        length += sprintf((char *)page + length,"\n%-16lu%s%-14lu%-15u",(unsigned long) ntohl(eg_entry->ctrl_info.cache_id), egress_state_string(eg_entry->entry_state), (eg_entry->ctrl_info.holding_time-(now.tv_sec-eg_entry->tv.tv_sec)), eg_entry->packets_rcvd);
                        length += sprintf((char *)page + length,"\n%-16lu%s%-14lu%-15u",(unsigned long) ntohl(eg_entry->ctrl_info.cache_id), egress_state_string(eg_entry->entry_state), (eg_entry->ctrl_info.holding_time-(now.tv_sec-eg_entry->tv.tv_sec)), eg_entry->packets_rcvd);
 
 
                        /* latest IP address */
                        /* latest IP address */
                        temp = (unsigned char *)&eg_entry->latest_ip_addr;
                        temp = (unsigned char *)&eg_entry->latest_ip_addr;
                        sprintf(ip_string, "%d.%d.%d.%d", temp[0], temp[1], temp[2], temp[3]);
                        sprintf(ip_string, "%d.%d.%d.%d", temp[0], temp[1], temp[2], temp[3]);
                        length += sprintf((char *)page + length, "%-16s", ip_string);
                        length += sprintf((char *)page + length, "%-16s", ip_string);
 
 
                        if(eg_entry->shortcut)
                        if(eg_entry->shortcut)
                                length += sprintf((char *)page + length," %-3d %-3d",eg_entry->shortcut->vpi,eg_entry->shortcut->vci);
                                length += sprintf((char *)page + length," %-3d %-3d",eg_entry->shortcut->vpi,eg_entry->shortcut->vci);
                        length += sprintf((char *)page + length,"\n");
                        length += sprintf((char *)page + length,"\n");
                        eg_entry = eg_entry->next;
                        eg_entry = eg_entry->next;
                }
                }
                length += sprintf((char *)page + length,"\n");
                length += sprintf((char *)page + length,"\n");
                mpc = mpc->next;
                mpc = mpc->next;
        }
        }
 
 
        if (*pos >= length) length = 0;
        if (*pos >= length) length = 0;
        else {
        else {
          if ((count + *pos) > length) count = length - *pos;
          if ((count + *pos) > length) count = length - *pos;
          if (copy_to_user(buff, (char *)page , count)) {
          if (copy_to_user(buff, (char *)page , count)) {
                  free_page(page);
                  free_page(page);
                  return -EFAULT;
                  return -EFAULT;
          }
          }
          *pos += count;
          *pos += count;
        }
        }
 
 
        free_page(page);
        free_page(page);
        return length;
        return length;
}
}
 
 
static ssize_t proc_mpc_write(struct file *file, const char *buff,
static ssize_t proc_mpc_write(struct file *file, const char *buff,
                              size_t nbytes, loff_t *ppos)
                              size_t nbytes, loff_t *ppos)
{
{
        int incoming, error, retval;
        int incoming, error, retval;
        char *page, c;
        char *page, c;
        const char *tmp;
        const char *tmp;
 
 
        if (nbytes == 0) return 0;
        if (nbytes == 0) return 0;
        if (nbytes >= PAGE_SIZE) nbytes = PAGE_SIZE-1;
        if (nbytes >= PAGE_SIZE) nbytes = PAGE_SIZE-1;
 
 
        error = verify_area(VERIFY_READ, buff, nbytes);
        error = verify_area(VERIFY_READ, buff, nbytes);
        if (error) return error;
        if (error) return error;
 
 
        page = (char *)__get_free_page(GFP_KERNEL);
        page = (char *)__get_free_page(GFP_KERNEL);
        if (page == NULL) return -ENOMEM;
        if (page == NULL) return -ENOMEM;
 
 
        incoming = 0;
        incoming = 0;
        tmp = buff;
        tmp = buff;
        while(incoming < nbytes){
        while(incoming < nbytes){
                if (get_user(c, tmp++)) return -EFAULT;
                if (get_user(c, tmp++)) return -EFAULT;
                incoming++;
                incoming++;
                if (c == '\0' || c == '\n')
                if (c == '\0' || c == '\n')
                        break;
                        break;
        }
        }
 
 
        retval = copy_from_user(page, buff, incoming);
        retval = copy_from_user(page, buff, incoming);
        if (retval != 0) {
        if (retval != 0) {
                printk("mpoa: proc_mpc_write: copy_from_user() failed\n");
                printk("mpoa: proc_mpc_write: copy_from_user() failed\n");
                return -EFAULT;
                return -EFAULT;
        }
        }
 
 
        *ppos += incoming;
        *ppos += incoming;
 
 
        page[incoming] = '\0';
        page[incoming] = '\0';
        retval = parse_qos(page, incoming);
        retval = parse_qos(page, incoming);
        if (retval == 0)
        if (retval == 0)
                printk("mpoa: proc_mpc_write: could not parse '%s'\n", page);
                printk("mpoa: proc_mpc_write: could not parse '%s'\n", page);
 
 
        free_page((unsigned long)page);
        free_page((unsigned long)page);
 
 
        return nbytes;
        return nbytes;
}
}
 
 
static int parse_qos(const char *buff, int len)
static int parse_qos(const char *buff, int len)
{
{
        /* possible lines look like this
        /* possible lines look like this
         * add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
         * add 130.230.54.142 tx=max_pcr,max_sdu rx=max_pcr,max_sdu
         */
         */
 
 
        int pos, i;
        int pos, i;
        uint32_t ipaddr;
        uint32_t ipaddr;
        unsigned char ip[4];
        unsigned char ip[4];
        char cmd[4], temp[256];
        char cmd[4], temp[256];
        const char *tmp, *prev;
        const char *tmp, *prev;
        struct atm_qos qos;
        struct atm_qos qos;
        int value[5];
        int value[5];
 
 
        memset(&qos, 0, sizeof(struct atm_qos));
        memset(&qos, 0, sizeof(struct atm_qos));
        strncpy(cmd, buff, 3);
        strncpy(cmd, buff, 3);
        if( strncmp(cmd,"add", 3) &&  strncmp(cmd,"del", 3))
        if( strncmp(cmd,"add", 3) &&  strncmp(cmd,"del", 3))
                return 0;  /* not add or del */
                return 0;  /* not add or del */
 
 
        pos = 4;
        pos = 4;
        /* next parse ip */
        /* next parse ip */
        prev = buff + pos;
        prev = buff + pos;
        for (i = 0; i < 3; i++) {
        for (i = 0; i < 3; i++) {
                tmp = strchr(prev, '.');
                tmp = strchr(prev, '.');
                if (tmp == NULL) return 0;
                if (tmp == NULL) return 0;
                memset(temp, '\0', 256);
                memset(temp, '\0', 256);
                memcpy(temp, prev, tmp-prev);
                memcpy(temp, prev, tmp-prev);
                ip[i] = (char)simple_strtoul(temp, NULL, 0);
                ip[i] = (char)simple_strtoul(temp, NULL, 0);
                tmp ++;
                tmp ++;
                prev = tmp;
                prev = tmp;
        }
        }
        tmp = strchr(prev, ' ');
        tmp = strchr(prev, ' ');
        if (tmp == NULL) return 0;
        if (tmp == NULL) return 0;
        memset(temp, '\0', 256);
        memset(temp, '\0', 256);
        memcpy(temp, prev, tmp-prev);
        memcpy(temp, prev, tmp-prev);
        ip[i] = (char)simple_strtoul(temp, NULL, 0);
        ip[i] = (char)simple_strtoul(temp, NULL, 0);
        ipaddr = *(uint32_t *)ip;
        ipaddr = *(uint32_t *)ip;
 
 
        if(!strncmp(cmd, "del", 3))
        if(!strncmp(cmd, "del", 3))
                 return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
                 return atm_mpoa_delete_qos(atm_mpoa_search_qos(ipaddr));
 
 
        /* next transmit values */
        /* next transmit values */
        tmp = strstr(buff, "tx=");
        tmp = strstr(buff, "tx=");
        if(tmp == NULL) return 0;
        if(tmp == NULL) return 0;
        tmp += 3;
        tmp += 3;
        prev = tmp;
        prev = tmp;
        for( i = 0; i < 1; i++){
        for( i = 0; i < 1; i++){
                 tmp = strchr(prev, ',');
                 tmp = strchr(prev, ',');
                 if (tmp == NULL) return 0;
                 if (tmp == NULL) return 0;
                 memset(temp, '\0', 256);
                 memset(temp, '\0', 256);
                 memcpy(temp, prev, tmp-prev);
                 memcpy(temp, prev, tmp-prev);
                 value[i] = (int)simple_strtoul(temp, NULL, 0);
                 value[i] = (int)simple_strtoul(temp, NULL, 0);
                 tmp ++;
                 tmp ++;
                 prev = tmp;
                 prev = tmp;
        }
        }
        tmp = strchr(prev, ' ');
        tmp = strchr(prev, ' ');
        if (tmp == NULL) return 0;
        if (tmp == NULL) return 0;
        memset(temp, '\0', 256);
        memset(temp, '\0', 256);
        memcpy(temp, prev, tmp-prev);
        memcpy(temp, prev, tmp-prev);
        value[i] = (int)simple_strtoul(temp, NULL, 0);
        value[i] = (int)simple_strtoul(temp, NULL, 0);
        qos.txtp.traffic_class = ATM_CBR;
        qos.txtp.traffic_class = ATM_CBR;
        qos.txtp.max_pcr = value[0];
        qos.txtp.max_pcr = value[0];
        qos.txtp.max_sdu = value[1];
        qos.txtp.max_sdu = value[1];
 
 
        /* next receive values */
        /* next receive values */
        tmp = strstr(buff, "rx=");
        tmp = strstr(buff, "rx=");
        if(tmp == NULL) return 0;
        if(tmp == NULL) return 0;
        if (strstr(buff, "rx=tx")) { /* rx == tx */
        if (strstr(buff, "rx=tx")) { /* rx == tx */
                qos.rxtp.traffic_class = qos.txtp.traffic_class;
                qos.rxtp.traffic_class = qos.txtp.traffic_class;
                qos.rxtp.max_pcr = qos.txtp.max_pcr;
                qos.rxtp.max_pcr = qos.txtp.max_pcr;
                qos.rxtp.max_cdv = qos.txtp.max_cdv;
                qos.rxtp.max_cdv = qos.txtp.max_cdv;
                qos.rxtp.max_sdu = qos.txtp.max_sdu;
                qos.rxtp.max_sdu = qos.txtp.max_sdu;
        } else {
        } else {
                tmp += 3;
                tmp += 3;
                prev = tmp;
                prev = tmp;
                for( i = 0; i < 1; i++){
                for( i = 0; i < 1; i++){
                        tmp = strchr(prev, ',');
                        tmp = strchr(prev, ',');
                        if (tmp == NULL) return 0;
                        if (tmp == NULL) return 0;
                        memset(temp, '\0', 256);
                        memset(temp, '\0', 256);
                        memcpy(temp, prev, tmp-prev);
                        memcpy(temp, prev, tmp-prev);
                        value[i] = (int)simple_strtoul(temp, NULL, 0);
                        value[i] = (int)simple_strtoul(temp, NULL, 0);
                        tmp ++;
                        tmp ++;
                        prev = tmp;
                        prev = tmp;
                }
                }
                tmp = strchr(prev, '\0');
                tmp = strchr(prev, '\0');
                if (tmp == NULL) return 0;
                if (tmp == NULL) return 0;
                memset(temp, '\0', 256);
                memset(temp, '\0', 256);
                memcpy(temp, prev, tmp-prev);
                memcpy(temp, prev, tmp-prev);
                value[i] = (int)simple_strtoul(temp, NULL, 0);
                value[i] = (int)simple_strtoul(temp, NULL, 0);
                qos.rxtp.traffic_class = ATM_CBR;
                qos.rxtp.traffic_class = ATM_CBR;
                qos.rxtp.max_pcr = value[0];
                qos.rxtp.max_pcr = value[0];
                qos.rxtp.max_sdu = value[1];
                qos.rxtp.max_sdu = value[1];
        }
        }
        qos.aal = ATM_AAL5;
        qos.aal = ATM_AAL5;
        dprintk("mpoa: mpoa_proc.c: parse_qos(): setting qos paramameters to tx=%d,%d rx=%d,%d\n",
        dprintk("mpoa: mpoa_proc.c: parse_qos(): setting qos paramameters to tx=%d,%d rx=%d,%d\n",
                qos.txtp.max_pcr,
                qos.txtp.max_pcr,
                qos.txtp.max_sdu,
                qos.txtp.max_sdu,
                qos.rxtp.max_pcr,
                qos.rxtp.max_pcr,
                qos.rxtp.max_sdu
                qos.rxtp.max_sdu
                );
                );
 
 
        atm_mpoa_add_qos(ipaddr, &qos);
        atm_mpoa_add_qos(ipaddr, &qos);
        return 1;
        return 1;
}
}
 
 
/*
/*
 * INITIALIZATION function - called when module is initialized/loaded.
 * INITIALIZATION function - called when module is initialized/loaded.
 */
 */
int mpc_proc_init(void)
int mpc_proc_init(void)
{
{
        struct proc_dir_entry *p;
        struct proc_dir_entry *p;
 
 
        p = create_proc_entry(STAT_FILE_NAME, 0, atm_proc_root);
        p = create_proc_entry(STAT_FILE_NAME, 0, atm_proc_root);
        if (!p) {
        if (!p) {
                printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
                printk(KERN_ERR "Unable to initialize /proc/atm/%s\n", STAT_FILE_NAME);
                return -ENOMEM;
                return -ENOMEM;
        }
        }
        p->proc_fops = &mpc_file_operations;
        p->proc_fops = &mpc_file_operations;
        p->owner = THIS_MODULE;
        p->owner = THIS_MODULE;
        return 0;
        return 0;
}
}
 
 
/*
/*
 * DELETING function - called when module is removed.
 * DELETING function - called when module is removed.
 */
 */
void mpc_proc_clean(void)
void mpc_proc_clean(void)
{
{
        remove_proc_entry(STAT_FILE_NAME,atm_proc_root);
        remove_proc_entry(STAT_FILE_NAME,atm_proc_root);
}
}
 
 
 
 
#endif /* CONFIG_PROC_FS */
#endif /* CONFIG_PROC_FS */
 
 
 
 
 
 
 
 
 
 
 
 
 
 

powered by: WebSVN 2.1.0

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