Commit 081fc6c7 authored by David S. Miller's avatar David S. Miller

Merge davem@nuts.ninka.net:/disk1/davem/BK/net-2.5

into kernel.bkbits.net:/home/davem/net-2.5
parents 36f1b589 ee2dea7d
...@@ -57,6 +57,7 @@ static int c_show(struct seq_file *m, void *p) ...@@ -57,6 +57,7 @@ static int c_show(struct seq_file *m, void *p)
switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) { switch (alg->cra_flags & CRYPTO_ALG_TYPE_MASK) {
case CRYPTO_ALG_TYPE_CIPHER: case CRYPTO_ALG_TYPE_CIPHER:
seq_printf(m, "type : cipher\n");
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "min keysize : %u\n", seq_printf(m, "min keysize : %u\n",
alg->cra_cipher.cia_min_keysize); alg->cra_cipher.cia_min_keysize);
...@@ -65,10 +66,17 @@ static int c_show(struct seq_file *m, void *p) ...@@ -65,10 +66,17 @@ static int c_show(struct seq_file *m, void *p)
break; break;
case CRYPTO_ALG_TYPE_DIGEST: case CRYPTO_ALG_TYPE_DIGEST:
seq_printf(m, "type : digest\n");
seq_printf(m, "blocksize : %u\n", alg->cra_blocksize); seq_printf(m, "blocksize : %u\n", alg->cra_blocksize);
seq_printf(m, "digestsize : %u\n", seq_printf(m, "digestsize : %u\n",
alg->cra_digest.dia_digestsize); alg->cra_digest.dia_digestsize);
break; break;
case CRYPTO_ALG_TYPE_COMPRESS:
seq_printf(m, "type : compression\n");
break;
default:
seq_printf(m, "type : unknown\n");
break;
} }
seq_putc(m, '\n'); seq_putc(m, '\n');
......
...@@ -18,8 +18,4 @@ ...@@ -18,8 +18,4 @@
#define SIOCMKCLIP _IO('a',ATMIOC_CLIP) /* create IP interface */ #define SIOCMKCLIP _IO('a',ATMIOC_CLIP) /* create IP interface */
#ifdef __KERNEL__
extern const unsigned char llc_oui[6];
#endif
#endif #endif
...@@ -732,9 +732,10 @@ static int br2684_seq_show(struct seq_file *seq, void *v) ...@@ -732,9 +732,10 @@ static int br2684_seq_show(struct seq_file *seq, void *v)
#ifdef CONFIG_ATM_BR2684_IPFILTER #ifdef CONFIG_ATM_BR2684_IPFILTER
#define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte] #define b1(var, byte) ((u8 *) &brvcc->filter.var)[byte]
#define bs(var) b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3) #define bs(var) b1(var, 0), b1(var, 1), b1(var, 2), b1(var, 3)
if (brvcc->filter.netmask != 0 && pos-- == 0) if (brvcc->filter.netmask != 0)
return sprintf(buf, " filter=%d.%d.%d.%d/" seq_printf(seq, " filter=%d.%d.%d.%d/"
"%d.%d.%d.%d\n", bs(prefix), bs(netmask)); "%d.%d.%d.%d\n",
bs(prefix), bs(netmask));
#undef bs #undef bs
#undef b1 #undef b1
#endif /* CONFIG_ATM_BR2684_IPFILTER */ #endif /* CONFIG_ATM_BR2684_IPFILTER */
......
...@@ -189,6 +189,13 @@ static int clip_arp_rcv(struct sk_buff *skb) ...@@ -189,6 +189,13 @@ static int clip_arp_rcv(struct sk_buff *skb)
return 0; return 0;
} }
static const unsigned char llc_oui[] = {
0xaa, /* DSAP: non-ISO */
0xaa, /* SSAP: non-ISO */
0x03, /* Ctrl: Unnumbered Information Command PDU */
0x00, /* OUI: EtherType */
0x00,
0x00 };
static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb) static void clip_push(struct atm_vcc *vcc,struct sk_buff *skb)
{ {
......
...@@ -22,15 +22,6 @@ ...@@ -22,15 +22,6 @@
#endif #endif
const unsigned char llc_oui[] = {
0xaa, /* DSAP: non-ISO */
0xaa, /* SSAP: non-ISO */
0x03, /* Ctrl: Unnumbered Information Command PDU */
0x00, /* OUI: EtherType */
0x00,
0x00 };
/* /*
* skb_migrate appends the list at "from" to "to", emptying "from" in the * skb_migrate appends the list at "from" to "to", emptying "from" in the
* process. skb_migrate is atomic with respect to all other skb operations on * process. skb_migrate is atomic with respect to all other skb operations on
...@@ -67,5 +58,4 @@ void skb_migrate(struct sk_buff_head *from,struct sk_buff_head *to) ...@@ -67,5 +58,4 @@ void skb_migrate(struct sk_buff_head *from,struct sk_buff_head *to)
} }
EXPORT_SYMBOL(llc_oui);
EXPORT_SYMBOL(skb_migrate); EXPORT_SYMBOL(skb_migrate);
/* net/atm/proc.c - ATM /proc interface */ /* net/atm/proc.c - ATM /proc interface
*
/* Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA */ * Written 1995-2000 by Werner Almesberger, EPFL LRC/ICA
/*
* The mechanism used here isn't designed for speed but rather for convenience
* of implementation. We only return one entry per read system call, so we can
* be reasonably sure not to overrun the page and race conditions may lead to
* the addition or omission of some lines but never to any corruption of a
* line's internal structure.
* *
* Making the whole thing slightly more efficient is left as an exercise to the * seq_file api usage by romieu@fr.zoreil.com
* reader. (Suggestions: wrapper which loops to get several entries per system *
* call; or make --left slightly more clever to avoid O(n^2) characteristics.) * Evaluating the efficiency of the whole thing if left as an exercise to
* I find it fast enough on my unloaded 266 MHz Pentium 2 :-) * the reader.
*/ */
#include <linux/config.h> #include <linux/config.h>
#include <linux/module.h> /* for EXPORT_SYMBOL */ #include <linux/module.h> /* for EXPORT_SYMBOL */
#include <linux/string.h> #include <linux/string.h>
...@@ -24,6 +16,7 @@ ...@@ -24,6 +16,7 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/stat.h> #include <linux/stat.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/atm.h> #include <linux/atm.h>
#include <linux/atmdev.h> #include <linux/atmdev.h>
...@@ -51,119 +44,202 @@ ...@@ -51,119 +44,202 @@
static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count, static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
loff_t *pos); loff_t *pos);
static ssize_t proc_spec_atm_read(struct file *file,char *buf,size_t count,
loff_t *pos);
static struct file_operations proc_dev_atm_operations = { static struct file_operations proc_atm_dev_ops = {
.owner = THIS_MODULE, .owner = THIS_MODULE,
.read = proc_dev_atm_read, .read = proc_dev_atm_read,
}; };
static struct file_operations proc_spec_atm_operations = { static void add_stats(struct seq_file *seq, const char *aal,
.owner = THIS_MODULE,
.read = proc_spec_atm_read,
};
static void add_stats(char *buf,const char *aal,
const struct k_atm_aal_stats *stats) const struct k_atm_aal_stats *stats)
{ {
sprintf(strchr(buf,0),"%s ( %d %d %d %d %d )",aal, seq_printf(seq, "%s ( %d %d %d %d %d )", aal,
atomic_read(&stats->tx),atomic_read(&stats->tx_err), atomic_read(&stats->tx),atomic_read(&stats->tx_err),
atomic_read(&stats->rx),atomic_read(&stats->rx_err), atomic_read(&stats->rx),atomic_read(&stats->rx_err),
atomic_read(&stats->rx_drop)); atomic_read(&stats->rx_drop));
} }
static void atm_dev_info(struct seq_file *seq, const struct atm_dev *dev)
static void atm_dev_info(const struct atm_dev *dev,char *buf)
{ {
int off,i; int i;
off = sprintf(buf,"%3d %-8s",dev->number,dev->type); seq_printf(seq, "%3d %-8s", dev->number, dev->type);
for (i = 0; i < ESI_LEN; i++) for (i = 0; i < ESI_LEN; i++)
off += sprintf(buf+off,"%02x",dev->esi[i]); seq_printf(seq, "%02x", dev->esi[i]);
strcat(buf," "); seq_puts(seq, " ");
add_stats(buf,"0",&dev->stats.aal0); add_stats(seq, "0", &dev->stats.aal0);
strcat(buf," "); seq_puts(seq, " ");
add_stats(buf,"5",&dev->stats.aal5); add_stats(seq, "5", &dev->stats.aal5);
sprintf(strchr(buf,0), "\t[%d]", atomic_read(&dev->refcnt)); seq_printf(seq, "\t[%d]", atomic_read(&dev->refcnt));
strcat(buf,"\n"); seq_putc(seq, '\n');
} }
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
static void svc_addr(struct seq_file *seq, struct sockaddr_atmsvc *addr)
static int svc_addr(char *buf,struct sockaddr_atmsvc *addr)
{ {
static int code[] = { 1,2,10,6,1,0 }; static int code[] = { 1,2,10,6,1,0 };
static int e164[] = { 1,8,4,6,1,0 }; static int e164[] = { 1,8,4,6,1,0 };
int *fields;
int len,i,j,pos;
len = 0;
if (*addr->sas_addr.pub) { if (*addr->sas_addr.pub) {
strcpy(buf,addr->sas_addr.pub); seq_printf(seq, "%s", addr->sas_addr.pub);
len = strlen(addr->sas_addr.pub); if (*addr->sas_addr.prv)
buf += len; seq_putc(seq, '+');
if (*addr->sas_addr.prv) { } else if (!*addr->sas_addr.prv) {
*buf++ = '+'; seq_printf(seq, "%s", "(none)");
len++; return;
}
} }
else if (!*addr->sas_addr.prv) {
strcpy(buf,"(none)");
return strlen(buf);
}
if (*addr->sas_addr.prv) { if (*addr->sas_addr.prv) {
len += 44; unsigned char *prv = addr->sas_addr.prv;
pos = 0; int *fields;
fields = *addr->sas_addr.prv == ATM_AFI_E164 ? e164 : code; int i, j;
fields = *prv == ATM_AFI_E164 ? e164 : code;
for (i = 0; fields[i]; i++) { for (i = 0; fields[i]; i++) {
for (j = fields[i]; j; j--) { for (j = fields[i]; j; j--)
sprintf(buf,"%02X",addr->sas_addr.prv[pos++]); seq_printf(seq, "%02X", *prv++);
buf += 2; if (fields[i+1])
} seq_putc(seq, '.');
if (fields[i+1]) *buf++ = '.';
} }
} }
return len;
} }
static void atmarp_info(struct seq_file *seq, struct net_device *dev,
static void atmarp_info(struct net_device *dev,struct atmarp_entry *entry, struct atmarp_entry *entry, struct clip_vcc *clip_vcc)
struct clip_vcc *clip_vcc,char *buf)
{ {
unsigned char *ip; char buf[17];
int svc,off,ip_len; int svc, off;
svc = !clip_vcc || clip_vcc->vcc->sk->sk_family == AF_ATMSVC; svc = !clip_vcc || clip_vcc->vcc->sk->sk_family == AF_ATMSVC;
off = sprintf(buf,"%-6s%-4s%-4s%5ld ",dev->name,svc ? "SVC" : "PVC", seq_printf(seq, "%-6s%-4s%-4s%5ld ", dev->name, svc ? "SVC" : "PVC",
!clip_vcc || clip_vcc->encap ? "LLC" : "NULL", !clip_vcc || clip_vcc->encap ? "LLC" : "NULL",
(jiffies-(clip_vcc ? clip_vcc->last_use : entry->neigh->used))/ (jiffies-(clip_vcc ? clip_vcc->last_use : entry->neigh->used))/HZ);
HZ);
ip = (unsigned char *) &entry->ip; off = snprintf(buf, sizeof(buf) - 1, "%d.%d.%d.%d", NIPQUAD(entry->ip));
ip_len = sprintf(buf+off,"%d.%d.%d.%d",ip[0],ip[1],ip[2],ip[3]); while (off < 16)
off += ip_len; buf[off++] = ' ';
while (ip_len++ < 16) buf[off++] = ' '; buf[off] = '\0';
if (!clip_vcc) seq_printf(seq, "%s", buf);
if (!clip_vcc) {
if (time_before(jiffies, entry->expires)) if (time_before(jiffies, entry->expires))
strcpy(buf+off,"(resolving)\n"); seq_printf(seq, "(resolving)\n");
else sprintf(buf+off,"(expired, ref %d)\n", else
atomic_read(&entry->neigh->refcnt)); seq_printf(seq, "(expired, ref %d)\n",
else if (!svc) atomic_read(&entry->neigh->refcnt));
sprintf(buf+off,"%d.%d.%d\n",clip_vcc->vcc->dev->number, } else if (!svc) {
clip_vcc->vcc->vpi,clip_vcc->vcc->vci); seq_printf(seq, "%d.%d.%d\n", clip_vcc->vcc->dev->number,
else { clip_vcc->vcc->vpi, clip_vcc->vcc->vci);
off += svc_addr(buf+off,&clip_vcc->vcc->remote); } else {
strcpy(buf+off,"\n"); svc_addr(seq, &clip_vcc->vcc->remote);
} seq_putc(seq, '\n');
}
}
#endif /* CONFIG_ATM_CLIP */
struct vcc_state {
struct sock *sk;
int family;
int clip_info;
};
static inline int compare_family(struct sock *sk, int family)
{
struct atm_vcc *vcc = atm_sk(sk);
return !family || (vcc->sk->sk_family == family);
} }
static int __vcc_walk(struct sock **sock, int family, loff_t l)
{
struct sock *sk = *sock;
if (sk == (void *)1) {
sk = hlist_empty(&vcc_sklist) ? NULL : __sk_head(&vcc_sklist);
l--;
}
for (; sk; sk = sk_next(sk)) {
l -= compare_family(sk, family);
if (l < 0)
goto out;
}
sk = (void *)1;
out:
*sock = sk;
return (l < 0);
}
static inline void *vcc_walk(struct vcc_state *state, loff_t l)
{
return __vcc_walk(&state->sk, state->family, l) ?
state : NULL;
}
static int __vcc_seq_open(struct inode *inode, struct file *file,
int family, struct seq_operations *ops)
{
struct vcc_state *state;
struct seq_file *seq;
int rc = -ENOMEM;
state = kmalloc(sizeof(*state), GFP_KERNEL);
if (!state)
goto out;
rc = seq_open(file, ops);
if (rc)
goto out_kfree;
state->family = family;
state->clip_info = try_atm_clip_ops();
seq = file->private_data;
seq->private = state;
out:
return rc;
out_kfree:
kfree(state);
goto out;
}
static int vcc_seq_release(struct inode *inode, struct file *file)
{
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
struct seq_file *seq = file->private_data;
struct vcc_state *state = seq->private;
if (state->clip_info)
module_put(atm_clip_ops->owner);
#endif #endif
return seq_release_private(inode, file);
}
static void *vcc_seq_start(struct seq_file *seq, loff_t *pos)
{
struct vcc_state *state = seq->private;
loff_t left = *pos;
read_lock(&vcc_sklist_lock);
state->sk = (void *)1;
return left ? vcc_walk(state, left) : (void *)1;
}
static void pvc_info(struct atm_vcc *vcc, char *buf, int clip_info) static void vcc_seq_stop(struct seq_file *seq, void *v)
{
read_unlock(&vcc_sklist_lock);
}
static void *vcc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct vcc_state *state = seq->private;
v = vcc_walk(state, 1);
*pos += !!PTR_ERR(v);
return v;
}
static void pvc_info(struct seq_file *seq, struct atm_vcc *vcc, int clip_info)
{ {
static const char *class_name[] = { "off","UBR","CBR","VBR","ABR" }; static const char *class_name[] = { "off","UBR","CBR","VBR","ABR" };
static const char *aal_name[] = { static const char *aal_name[] = {
...@@ -171,9 +247,8 @@ static void pvc_info(struct atm_vcc *vcc, char *buf, int clip_info) ...@@ -171,9 +247,8 @@ static void pvc_info(struct atm_vcc *vcc, char *buf, int clip_info)
"???", "5", "???", "???", /* 4- 7 */ "???", "5", "???", "???", /* 4- 7 */
"???", "???", "???", "???", /* 8-11 */ "???", "???", "???", "???", /* 8-11 */
"???", "0", "???", "???"}; /* 12-15 */ "???", "0", "???", "???"}; /* 12-15 */
int off;
off = sprintf(buf,"%3d %3d %5d %-3s %7d %-5s %7d %-6s", seq_printf(seq, "%3d %3d %5d %-3s %7d %-5s %7d %-6s",
vcc->dev->number,vcc->vpi,vcc->vci, vcc->dev->number,vcc->vpi,vcc->vci,
vcc->qos.aal >= sizeof(aal_name)/sizeof(aal_name[0]) ? "err" : vcc->qos.aal >= sizeof(aal_name)/sizeof(aal_name[0]) ? "err" :
aal_name[vcc->qos.aal],vcc->qos.rxtp.min_pcr, aal_name[vcc->qos.aal],vcc->qos.rxtp.min_pcr,
...@@ -185,18 +260,14 @@ static void pvc_info(struct atm_vcc *vcc, char *buf, int clip_info) ...@@ -185,18 +260,14 @@ static void pvc_info(struct atm_vcc *vcc, char *buf, int clip_info)
struct net_device *dev; struct net_device *dev;
dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL; dev = clip_vcc->entry ? clip_vcc->entry->neigh->dev : NULL;
off += sprintf(buf+off,"CLIP, Itf:%s, Encap:", seq_printf(seq, "CLIP, Itf:%s, Encap:",
dev ? dev->name : "none?"); dev ? dev->name : "none?");
if (clip_vcc->encap) seq_printf(seq, "%s", clip_vcc->encap ? "LLC/SNAP" : "None");
off += sprintf(buf+off,"LLC/SNAP");
else
off += sprintf(buf+off,"None");
} }
#endif #endif
strcpy(buf+off,"\n"); seq_putc(seq, '\n');
} }
static const char *vcc_state(struct atm_vcc *vcc) static const char *vcc_state(struct atm_vcc *vcc)
{ {
static const char *map[] = { ATM_VS2TXT_MAP }; static const char *map[] = { ATM_VS2TXT_MAP };
...@@ -204,337 +275,592 @@ static const char *vcc_state(struct atm_vcc *vcc) ...@@ -204,337 +275,592 @@ static const char *vcc_state(struct atm_vcc *vcc)
return map[ATM_VF2VS(vcc->flags)]; return map[ATM_VF2VS(vcc->flags)];
} }
static void vcc_info(struct seq_file *seq, struct atm_vcc *vcc)
static void vc_info(struct atm_vcc *vcc,char *buf)
{ {
char *here; seq_printf(seq, "%p ", vcc);
if (!vcc->dev)
here = buf+sprintf(buf,"%p ",vcc); seq_printf(seq, "Unassigned ");
if (!vcc->dev) here += sprintf(here,"Unassigned "); else
else here += sprintf(here,"%3d %3d %5d ",vcc->dev->number,vcc->vpi, seq_printf(seq, "%3d %3d %5d ", vcc->dev->number, vcc->vpi,
vcc->vci); vcc->vci);
switch (vcc->sk->sk_family) { switch (vcc->sk->sk_family) {
case AF_ATMPVC: case AF_ATMPVC:
here += sprintf(here,"PVC"); seq_printf(seq, "PVC");
break; break;
case AF_ATMSVC: case AF_ATMSVC:
here += sprintf(here,"SVC"); seq_printf(seq, "SVC");
break; break;
default: default:
here += sprintf(here, "%3d", vcc->sk->sk_family); seq_printf(seq, "%3d", vcc->sk->sk_family);
} }
here += sprintf(here," %04lx %5d %7d/%7d %7d/%7d\n",vcc->flags, seq_printf(seq, " %04lx %5d %7d/%7d %7d/%7d\n", vcc->flags, vcc->sk->sk_err,
vcc->sk->sk_err, atomic_read(&vcc->sk->sk_wmem_alloc),vcc->sk->sk_sndbuf,
atomic_read(&vcc->sk->sk_wmem_alloc), vcc->sk->sk_sndbuf, atomic_read(&vcc->sk->sk_rmem_alloc),vcc->sk->sk_rcvbuf);
atomic_read(&vcc->sk->sk_rmem_alloc), vcc->sk->sk_rcvbuf);
} }
static void svc_info(struct seq_file *seq, struct atm_vcc *vcc)
static void svc_info(struct atm_vcc *vcc,char *buf)
{ {
char *here;
int i;
if (!vcc->dev) if (!vcc->dev)
sprintf(buf,sizeof(void *) == 4 ? "N/A@%p%10s" : "N/A@%p%2s", seq_printf(seq, sizeof(void *) == 4 ?
vcc,""); "N/A@%p%10s" : "N/A@%p%2s", vcc, "");
else sprintf(buf,"%3d %3d %5d ",vcc->dev->number,vcc->vpi, else
vcc->vci); seq_printf(seq, "%3d %3d %5d ",
here = strchr(buf,0); vcc->dev->number, vcc->vpi, vcc->vci);
here += sprintf(here,"%-10s ",vcc_state(vcc)); seq_printf(seq, "%-10s ", vcc_state(vcc));
here += sprintf(here,"%s%s",vcc->remote.sas_addr.pub, seq_printf(seq, "%s%s", vcc->remote.sas_addr.pub,
*vcc->remote.sas_addr.pub && *vcc->remote.sas_addr.prv ? "+" : ""); *vcc->remote.sas_addr.pub && *vcc->remote.sas_addr.prv ? "+" : "");
if (*vcc->remote.sas_addr.prv) if (*vcc->remote.sas_addr.prv) {
int i;
for (i = 0; i < ATM_ESA_LEN; i++) for (i = 0; i < ATM_ESA_LEN; i++)
here += sprintf(here,"%02x", seq_printf(seq, "%02x", vcc->remote.sas_addr.prv[i]);
vcc->remote.sas_addr.prv[i]); }
strcat(here,"\n"); seq_putc(seq, '\n');
} }
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
static char* static char* lec_arp_get_status_string(unsigned char status)
lec_arp_get_status_string(unsigned char status)
{ {
switch(status) { static char *lec_arp_status_string[] = {
case ESI_UNKNOWN: "ESI_UNKNOWN ",
return "ESI_UNKNOWN "; "ESI_ARP_PENDING ",
case ESI_ARP_PENDING: "ESI_VC_PENDING ",
return "ESI_ARP_PENDING "; "<Unknown> ",
case ESI_VC_PENDING: "ESI_FLUSH_PENDING ",
return "ESI_VC_PENDING "; "ESI_FORWARD_DIRECT",
case ESI_FLUSH_PENDING: "<Undefined>"
return "ESI_FLUSH_PENDING "; };
case ESI_FORWARD_DIRECT:
return "ESI_FORWARD_DIRECT"; if (status > ESI_FORWARD_DIRECT)
default: status = ESI_FORWARD_DIRECT + 1;
return "<Unknown> "; return lec_arp_status_string[status];
}
} }
static void static void lec_info(struct seq_file *seq, struct lec_arp_table *entry)
lec_info(struct lec_arp_table *entry, char *buf)
{ {
int j, offset=0; int i;
for(j=0;j<ETH_ALEN;j++) { for (i = 0; i < ETH_ALEN; i++)
offset+=sprintf(buf+offset,"%2.2x",0xff&entry->mac_addr[j]); seq_printf(seq, "%2.2x", entry->mac_addr[i] & 0xff);
} seq_printf(seq, " ");
offset+=sprintf(buf+offset, " "); for (i = 0; i < ATM_ESA_LEN; i++)
for(j=0;j<ATM_ESA_LEN;j++) { seq_printf(seq, "%2.2x", entry->atm_addr[i] & 0xff);
offset+=sprintf(buf+offset,"%2.2x",0xff&entry->atm_addr[j]); seq_printf(seq, " %s %4.4x", lec_arp_get_status_string(entry->status),
entry->flags & 0xffff);
if (entry->vcc)
seq_printf(seq, "%3d %3d ", entry->vcc->vpi, entry->vcc->vci);
else
seq_printf(seq, " ");
if (entry->recv_vcc) {
seq_printf(seq, " %3d %3d", entry->recv_vcc->vpi,
entry->recv_vcc->vci);
} }
offset+=sprintf(buf+offset, " %s %4.4x", seq_putc(seq, '\n');
lec_arp_get_status_string(entry->status),
entry->flags&0xffff);
if (entry->vcc) {
offset+=sprintf(buf+offset, "%3d %3d ", entry->vcc->vpi,
entry->vcc->vci);
} else
offset+=sprintf(buf+offset, " ");
if (entry->recv_vcc) {
offset+=sprintf(buf+offset, " %3d %3d",
entry->recv_vcc->vpi, entry->recv_vcc->vci);
}
sprintf(buf+offset,"\n");
} }
#endif #endif /* CONFIG_ATM_LANE */
static int atm_devices_info(loff_t pos,char *buf) static int atm_dev_seq_show(struct seq_file *seq, void *v)
{ {
struct atm_dev *dev; static char atm_dev_banner[] =
struct list_head *p; "Itf Type ESI/\"MAC\"addr "
int left; "AAL(TX,err,RX,err,drop) ... [refcnt]\n";
if (v == (void *)1)
seq_puts(seq, atm_dev_banner);
else {
struct atm_dev *dev = list_entry(v, struct atm_dev, dev_list);
if (!pos) { atm_dev_info(seq, dev);
return sprintf(buf,"Itf Type ESI/\"MAC\"addr "
"AAL(TX,err,RX,err,drop) ... [refcnt]\n");
} }
left = pos-1; return 0;
spin_lock(&atm_dev_lock); }
list_for_each(p, &atm_devs) {
dev = list_entry(p, struct atm_dev, dev_list); static struct seq_operations atm_dev_seq_ops = {
if (left-- == 0) { .start = atm_dev_seq_start,
atm_dev_info(dev,buf); .next = atm_dev_seq_next,
spin_unlock(&atm_dev_lock); .stop = atm_dev_seq_stop,
return strlen(buf); .show = atm_dev_seq_show,
} };
static int atm_dev_seq_open(struct inode *inode, struct file *file)
{
return seq_open(file, &atm_dev_seq_ops);
}
static struct file_operations devices_seq_fops = {
.open = atm_dev_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release,
};
static int pvc_seq_show(struct seq_file *seq, void *v)
{
static char atm_pvc_banner[] =
"Itf VPI VCI AAL RX(PCR,Class) TX(PCR,Class)\n";
if (v == (void *)1)
seq_puts(seq, atm_pvc_banner);
else {
struct vcc_state *state = seq->private;
struct atm_vcc *vcc = atm_sk(state->sk);
pvc_info(seq, vcc, state->clip_info);
} }
spin_unlock(&atm_dev_lock);
return 0; return 0;
} }
/* static struct seq_operations pvc_seq_ops = {
* FIXME: it isn't safe to walk the VCC list without turning off interrupts. .start = vcc_seq_start,
* What is really needed is some lock on the devices. Ditto for ATMARP. .next = vcc_seq_next,
*/ .stop = vcc_seq_stop,
.show = pvc_seq_show,
};
static int atm_pvc_info(loff_t pos,char *buf) static int pvc_seq_open(struct inode *inode, struct file *file)
{ {
struct hlist_node *node; return __vcc_seq_open(inode, file, PF_ATMPVC, &pvc_seq_ops);
struct sock *s; }
struct atm_vcc *vcc;
int left, clip_info = 0;
if (!pos) { static struct file_operations pvc_seq_fops = {
return sprintf(buf,"Itf VPI VCI AAL RX(PCR,Class) " .open = pvc_seq_open,
"TX(PCR,Class)\n"); .read = seq_read,
} .llseek = seq_lseek,
left = pos-1; .release = vcc_seq_release,
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) };
if (try_atm_clip_ops())
clip_info = 1; static int vcc_seq_show(struct seq_file *seq, void *v)
#endif {
read_lock(&vcc_sklist_lock); if (v == (void *)1) {
sk_for_each(s, node, &vcc_sklist) { seq_printf(seq, sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s",
vcc = atm_sk(s); "Address ", "Itf VPI VCI Fam Flags Reply "
if (vcc->sk->sk_family == PF_ATMPVC && vcc->dev && !left--) { "Send buffer Recv buffer\n");
pvc_info(vcc,buf,clip_info); } else {
read_unlock(&vcc_sklist_lock); struct vcc_state *state = seq->private;
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) struct atm_vcc *vcc = atm_sk(state->sk);
if (clip_info)
module_put(atm_clip_ops->owner); vcc_info(seq, vcc);
#endif }
return strlen(buf); return 0;
} }
static struct seq_operations vcc_seq_ops = {
.start = vcc_seq_start,
.next = vcc_seq_next,
.stop = vcc_seq_stop,
.show = vcc_seq_show,
};
static int vcc_seq_open(struct inode *inode, struct file *file)
{
return __vcc_seq_open(inode, file, 0, &vcc_seq_ops);
}
static struct file_operations vcc_seq_fops = {
.open = vcc_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = vcc_seq_release,
};
static int svc_seq_show(struct seq_file *seq, void *v)
{
static char atm_svc_banner[] =
"Itf VPI VCI State Remote\n";
if (v == (void *)1)
seq_puts(seq, atm_svc_banner);
else {
struct vcc_state *state = seq->private;
struct atm_vcc *vcc = atm_sk(state->sk);
svc_info(seq, vcc);
} }
read_unlock(&vcc_sklist_lock);
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
if (clip_info)
module_put(atm_clip_ops->owner);
#endif
return 0; return 0;
} }
static struct seq_operations svc_seq_ops = {
.start = vcc_seq_start,
.next = vcc_seq_next,
.stop = vcc_seq_stop,
.show = svc_seq_show,
};
static int atm_vc_info(loff_t pos,char *buf) static int svc_seq_open(struct inode *inode, struct file *file)
{ {
struct atm_vcc *vcc; return __vcc_seq_open(inode, file, PF_ATMSVC, &svc_seq_ops);
struct hlist_node *node; }
struct sock *s;
int left;
if (!pos) static struct file_operations svc_seq_fops = {
return sprintf(buf,sizeof(void *) == 4 ? "%-8s%s" : "%-16s%s", .open = svc_seq_open,
"Address"," Itf VPI VCI Fam Flags Reply Send buffer" .read = seq_read,
" Recv buffer\n"); .llseek = seq_lseek,
left = pos-1; .release = vcc_seq_release,
read_lock(&vcc_sklist_lock); };
sk_for_each(s, node, &vcc_sklist) {
vcc = atm_sk(s);
if (!left--) {
vc_info(vcc,buf);
read_unlock(&vcc_sklist_lock);
return strlen(buf);
}
}
read_unlock(&vcc_sklist_lock);
return 0; #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
}
struct arp_state {
int bucket;
struct neighbour *n;
struct clip_vcc *vcc;
};
static void *arp_vcc_walk(struct arp_state *state,
struct atmarp_entry *e, loff_t *l)
{
struct clip_vcc *vcc = state->vcc;
if (!vcc)
vcc = e->vccs;
if (vcc == (void *)1) {
vcc = e->vccs;
--*l;
}
for (; vcc; vcc = vcc->next) {
if (--*l < 0)
break;
}
state->vcc = vcc;
return (*l < 0) ? state : NULL;
}
static void *arp_get_idx(struct arp_state *state, loff_t l)
{
void *v = NULL;
for (; state->bucket <= NEIGH_HASHMASK; state->bucket++) {
for (; state->n; state->n = state->n->next) {
v = arp_vcc_walk(state, NEIGH2ENTRY(state->n), &l);
if (v)
goto done;
}
state->n = clip_tbl_hook->hash_buckets[state->bucket + 1];
}
done:
return v;
}
static int atm_svc_info(loff_t pos,char *buf) static void *arp_seq_start(struct seq_file *seq, loff_t *pos)
{ {
struct hlist_node *node; struct arp_state *state = seq->private;
struct sock *s; void *ret = (void *)1;
struct atm_vcc *vcc;
int left;
if (!pos) if (!clip_tbl_hook) {
return sprintf(buf,"Itf VPI VCI State Remote\n"); state->bucket = -1;
left = pos-1; goto out;
read_lock(&vcc_sklist_lock);
sk_for_each(s, node, &vcc_sklist) {
vcc = atm_sk(s);
if (vcc->sk->sk_family == PF_ATMSVC && !left--) {
svc_info(vcc,buf);
read_unlock(&vcc_sklist_lock);
return strlen(buf);
}
} }
read_unlock(&vcc_sklist_lock);
return 0; read_lock_bh(&clip_tbl_hook->lock);
state->bucket = 0;
state->n = clip_tbl_hook->hash_buckets[0];
state->vcc = (void *)1;
if (*pos)
ret = arp_get_idx(state, *pos);
out:
return ret;
} }
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) static void arp_seq_stop(struct seq_file *seq, void *v)
static int atm_arp_info(loff_t pos,char *buf) {
struct arp_state *state = seq->private;
if (state->bucket != -1)
read_unlock_bh(&clip_tbl_hook->lock);
}
static void *arp_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{ {
struct neighbour *n; struct arp_state *state = seq->private;
int i,count;
if (!pos) { v = arp_get_idx(state, 1);
return sprintf(buf,"IPitf TypeEncp Idle IP address " *pos += !!PTR_ERR(v);
"ATM address\n"); return v;
}
static int arp_seq_show(struct seq_file *seq, void *v)
{
static char atm_arp_banner[] =
"IPitf TypeEncp Idle IP address ATM address\n";
if (v == (void *)1)
seq_puts(seq, atm_arp_banner);
else {
struct arp_state *state = seq->private;
struct neighbour *n = state->n;
struct clip_vcc *vcc = state->vcc;
atmarp_info(seq, n->dev, NEIGH2ENTRY(n), vcc);
} }
return 0;
}
static struct seq_operations arp_seq_ops = {
.start = arp_seq_start,
.next = arp_seq_next,
.stop = arp_seq_stop,
.show = arp_seq_show,
};
static int arp_seq_open(struct inode *inode, struct file *file)
{
struct arp_state *state;
struct seq_file *seq;
int rc = -EAGAIN;
if (!try_atm_clip_ops()) if (!try_atm_clip_ops())
return 0; goto out;
count = pos;
read_lock_bh(&clip_tbl_hook->lock); state = kmalloc(sizeof(*state), GFP_KERNEL);
for (i = 0; i <= NEIGH_HASHMASK; i++) if (!state) {
for (n = clip_tbl_hook->hash_buckets[i]; n; n = n->next) { rc = -ENOMEM;
struct atmarp_entry *entry = NEIGH2ENTRY(n); goto out_put;
struct clip_vcc *vcc; }
if (!entry->vccs) { rc = seq_open(file, &arp_seq_ops);
if (--count) continue; if (rc)
atmarp_info(n->dev,entry,NULL,buf); goto out_kfree;
read_unlock_bh(&clip_tbl_hook->lock);
module_put(atm_clip_ops->owner); seq = file->private_data;
return strlen(buf); seq->private = state;
} out:
for (vcc = entry->vccs; vcc; return rc;
vcc = vcc->next) {
if (--count) continue; out_put:
atmarp_info(n->dev,entry,vcc,buf);
read_unlock_bh(&clip_tbl_hook->lock);
module_put(atm_clip_ops->owner);
return strlen(buf);
}
}
read_unlock_bh(&clip_tbl_hook->lock);
module_put(atm_clip_ops->owner); module_put(atm_clip_ops->owner);
return 0; out_kfree:
kfree(state);
goto out;
} }
#endif
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) static int arp_seq_release(struct inode *inode, struct file *file)
static int atm_lec_info(loff_t pos,char *buf)
{ {
module_put(atm_clip_ops->owner);
return seq_release_private(inode, file);
}
static struct file_operations arp_seq_fops = {
.open = arp_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = arp_seq_release,
};
#endif /* CONFIG_ATM_CLIP */
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
struct lec_state {
unsigned long flags; unsigned long flags;
struct lec_priv *priv; struct lec_priv *locked;
struct lec_arp_table *entry; struct lec_arp_table *entry;
int i, count, d, e;
struct net_device *dev; struct net_device *dev;
int itf;
int arp_table;
int misc_table;
};
if (!pos) { static void *lec_tbl_walk(struct lec_state *state, struct lec_arp_table *tbl,
return sprintf(buf,"Itf MAC ATM destination" loff_t *l)
" Status Flags " {
"VPI/VCI Recv VPI/VCI\n"); struct lec_arp_table *e = state->entry;
if (!e)
e = tbl;
if (e == (void *)1) {
e = tbl;
--*l;
} }
if (!try_atm_lane_ops()) for (; e; e = e->next) {
return 0; /* the lane module is not there yet */ if (--*l < 0)
break;
count = pos; }
for(d = 0; d < MAX_LEC_ITF; d++) { state->entry = e;
dev = atm_lane_ops->get_lec(d); return (*l < 0) ? state : NULL;
if (!dev || !(priv = (struct lec_priv *) dev->priv)) }
continue;
spin_lock_irqsave(&priv->lec_arp_lock, flags); static void *lec_arp_walk(struct lec_state *state, loff_t *l,
for(i = 0; i < LEC_ARP_TABLE_SIZE; i++) { struct lec_priv *priv)
for(entry = priv->lec_arp_tables[i]; entry; entry = entry->next) { {
if (--count) void *v = NULL;
continue; int p;
e = sprintf(buf,"%s ", dev->name);
lec_info(entry, buf+e); for (p = state->arp_table; p < LEC_ARP_TABLE_SIZE; p++) {
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); v = lec_tbl_walk(state, priv->lec_arp_tables[p], l);
dev_put(dev); if (v)
module_put(atm_lane_ops->owner); break;
return strlen(buf); }
} state->arp_table = p;
} return v;
for(entry = priv->lec_arp_empty_ones; entry; entry = entry->next) { }
if (--count)
continue; static void *lec_misc_walk(struct lec_state *state, loff_t *l,
e = sprintf(buf,"%s ", dev->name); struct lec_priv *priv)
lec_info(entry, buf+e); {
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); struct lec_arp_table *lec_misc_tables[] = {
dev_put(dev); priv->lec_arp_empty_ones,
module_put(atm_lane_ops->owner); priv->lec_no_forward,
return strlen(buf); priv->mcast_fwds
} };
for(entry = priv->lec_no_forward; entry; entry=entry->next) { void *v = NULL;
if (--count) int q;
continue;
e = sprintf(buf,"%s ", dev->name); for (q = state->misc_table; q < ARRAY_SIZE(lec_misc_tables); q++) {
lec_info(entry, buf+e); v = lec_tbl_walk(state, lec_misc_tables[q], l);
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); if (v)
dev_put(dev); break;
module_put(atm_lane_ops->owner); }
return strlen(buf); state->misc_table = q;
} return v;
for(entry = priv->mcast_fwds; entry; entry = entry->next) { }
if (--count)
continue; static void *lec_priv_walk(struct lec_state *state, loff_t *l,
e = sprintf(buf,"%s ", dev->name); struct lec_priv *priv)
lec_info(entry, buf+e); {
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); if (!state->locked) {
dev_put(dev); state->locked = priv;
module_put(atm_lane_ops->owner); spin_lock_irqsave(&priv->lec_arp_lock, state->flags);
return strlen(buf); }
} if (!lec_arp_walk(state, l, priv) &&
spin_unlock_irqrestore(&priv->lec_arp_lock, flags); !lec_misc_walk(state, l, priv)) {
spin_unlock_irqrestore(&priv->lec_arp_lock, state->flags);
state->locked = NULL;
/* Partial state reset for the next time we get called */
state->arp_table = state->misc_table = 0;
}
return state->locked;
}
static void *lec_itf_walk(struct lec_state *state, loff_t *l)
{
struct net_device *dev;
void *v;
dev = state->dev ? state->dev : atm_lane_ops->get_lec(state->itf);
v = (dev && dev->priv) ? lec_priv_walk(state, l, dev->priv) : NULL;
if (!v && dev) {
dev_put(dev); dev_put(dev);
/* Partial state reset for the next time we get called */
dev = NULL;
}
state->dev = dev;
return v;
}
static void *lec_get_idx(struct lec_state *state, loff_t l)
{
void *v = NULL;
for (; state->itf < MAX_LEC_ITF; state->itf++) {
v = lec_itf_walk(state, &l);
if (v)
break;
}
return v;
}
static void *lec_seq_start(struct seq_file *seq, loff_t *pos)
{
struct lec_state *state = seq->private;
state->itf = 0;
state->dev = NULL;
state->locked = NULL;
state->arp_table = 0;
state->misc_table = 0;
state->entry = (void *)1;
return *pos ? lec_get_idx(state, *pos) : (void*)1;
}
static void lec_seq_stop(struct seq_file *seq, void *v)
{
struct lec_state *state = seq->private;
if (state->dev) {
spin_unlock_irqrestore(&state->locked->lec_arp_lock,
state->flags);
dev_put(state->dev);
}
}
static void *lec_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
struct lec_state *state = seq->private;
v = lec_get_idx(state, 1);
*pos += !!PTR_ERR(v);
return v;
}
static int lec_seq_show(struct seq_file *seq, void *v)
{
static char lec_banner[] = "Itf MAC ATM destination"
" Status Flags "
"VPI/VCI Recv VPI/VCI\n";
if (v == (void *)1)
seq_puts(seq, lec_banner);
else {
struct lec_state *state = seq->private;
struct net_device *dev = state->dev;
seq_printf(seq, "%s ", dev->name);
lec_info(seq, state->entry);
} }
module_put(atm_lane_ops->owner);
return 0; return 0;
} }
#endif
static struct seq_operations lec_seq_ops = {
.start = lec_seq_start,
.next = lec_seq_next,
.stop = lec_seq_stop,
.show = lec_seq_show,
};
static int lec_seq_open(struct inode *inode, struct file *file)
{
struct lec_state *state;
struct seq_file *seq;
int rc = -EAGAIN;
if (!try_atm_lane_ops())
goto out;
state = kmalloc(sizeof(*state), GFP_KERNEL);
if (!state) {
rc = -ENOMEM;
goto out;
}
rc = seq_open(file, &lec_seq_ops);
if (rc)
goto out_kfree;
seq = file->private_data;
seq->private = state;
out:
return rc;
out_kfree:
kfree(state);
goto out;
}
static int lec_seq_release(struct inode *inode, struct file *file)
{
module_put(atm_lane_ops->owner);
return seq_release_private(inode, file);
}
static struct file_operations lec_seq_fops = {
.open = lec_seq_open,
.read = seq_read,
.llseek = seq_lseek,
.release = lec_seq_release,
};
#endif /* CONFIG_ATM_LANE */
static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count, static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
loff_t *pos) loff_t *pos)
...@@ -562,28 +888,6 @@ static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count, ...@@ -562,28 +888,6 @@ static ssize_t proc_dev_atm_read(struct file *file,char *buf,size_t count,
} }
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 = PDE(file->f_dentry->d_inode)->data;
if (count == 0) return 0;
page = get_zeroed_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; struct proc_dir_entry *atm_proc_root;
EXPORT_SYMBOL(atm_proc_root); EXPORT_SYMBOL(atm_proc_root);
...@@ -604,19 +908,19 @@ int atm_proc_dev_register(struct atm_dev *dev) ...@@ -604,19 +908,19 @@ int atm_proc_dev_register(struct atm_dev *dev)
dev->proc_name = kmalloc(strlen(dev->type) + digits + 2, GFP_KERNEL); dev->proc_name = kmalloc(strlen(dev->type) + digits + 2, GFP_KERNEL);
if (!dev->proc_name) if (!dev->proc_name)
goto fail1; goto err_out;
sprintf(dev->proc_name,"%s:%d",dev->type, dev->number); sprintf(dev->proc_name,"%s:%d",dev->type, dev->number);
dev->proc_entry = create_proc_entry(dev->proc_name, 0, atm_proc_root); dev->proc_entry = create_proc_entry(dev->proc_name, 0, atm_proc_root);
if (!dev->proc_entry) if (!dev->proc_entry)
goto fail0; goto err_free_name;
dev->proc_entry->data = dev; dev->proc_entry->data = dev;
dev->proc_entry->proc_fops = &proc_dev_atm_operations; dev->proc_entry->proc_fops = &proc_atm_dev_ops;
dev->proc_entry->owner = THIS_MODULE; dev->proc_entry->owner = THIS_MODULE;
return 0; return 0;
fail0: err_free_name:
kfree(dev->proc_name); kfree(dev->proc_name);
fail1: err_out:
return error; return error;
} }
...@@ -630,57 +934,65 @@ void atm_proc_dev_deregister(struct atm_dev *dev) ...@@ -630,57 +934,65 @@ void atm_proc_dev_deregister(struct atm_dev *dev)
kfree(dev->proc_name); kfree(dev->proc_name);
} }
static struct atm_proc_entry {
char *name;
struct file_operations *proc_fops;
struct proc_dir_entry *dirent;
} atm_proc_ents[] = {
{ .name = "devices", .proc_fops = &devices_seq_fops },
{ .name = "pvc", .proc_fops = &pvc_seq_fops },
{ .name = "svc", .proc_fops = &svc_seq_fops },
{ .name = "vc", .proc_fops = &vcc_seq_fops },
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
{ .name = "arp", .proc_fops = &arp_seq_fops },
#endif
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
{ .name = "lec", .proc_fops = &lec_seq_fops },
#endif
{ .name = NULL, .proc_fops = NULL }
};
#define CREATE_ENTRY(name) \ static void atm_proc_dirs_remove(void)
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_MODULE
static struct proc_dir_entry *devices = NULL, *pvc = NULL,
*svc = NULL, *arp = NULL, *lec = NULL, *vc = NULL;
static void atm_proc_cleanup(void)
{ {
if (devices) static struct atm_proc_entry *e;
remove_proc_entry("devices",atm_proc_root);
if (pvc) for (e = atm_proc_ents; e->name; e++) {
remove_proc_entry("pvc",atm_proc_root); if (e->dirent)
if (svc) remove_proc_entry(e->name, atm_proc_root);
remove_proc_entry("svc",atm_proc_root); }
if (arp) remove_proc_entry("net/atm", NULL);
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);
} }
int __init atm_proc_init(void) int __init atm_proc_init(void)
{ {
static struct atm_proc_entry *e;
int ret;
atm_proc_root = proc_mkdir("net/atm",NULL); atm_proc_root = proc_mkdir("net/atm",NULL);
if (!atm_proc_root) if (!atm_proc_root)
return -ENOMEM; goto err_out;
CREATE_ENTRY(devices); for (e = atm_proc_ents; e->name; e++) {
CREATE_ENTRY(pvc); struct proc_dir_entry *dirent;
CREATE_ENTRY(svc);
CREATE_ENTRY(vc); dirent = create_proc_entry(e->name, S_IRUGO, atm_proc_root);
#if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE) if (!dirent)
CREATE_ENTRY(arp); goto err_out_remove;
#endif dirent->proc_fops = e->proc_fops;
#if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) dirent->owner = THIS_MODULE;
CREATE_ENTRY(lec); e->dirent = dirent;
#endif }
return 0; ret = 0;
out:
cleanup: return ret;
atm_proc_cleanup();
return -ENOMEM; err_out_remove:
atm_proc_dirs_remove();
err_out:
ret = -ENOMEM;
goto out;
} }
void atm_proc_exit(void) void __exit atm_proc_exit(void)
{ {
atm_proc_cleanup(); atm_proc_dirs_remove();
} }
...@@ -30,7 +30,7 @@ static struct atm_dev *__alloc_atm_dev(const char *type) ...@@ -30,7 +30,7 @@ static struct atm_dev *__alloc_atm_dev(const char *type)
{ {
struct atm_dev *dev; struct atm_dev *dev;
dev = kmalloc(sizeof(*dev), GFP_ATOMIC); dev = kmalloc(sizeof(*dev), GFP_KERNEL);
if (!dev) if (!dev)
return NULL; return NULL;
memset(dev, 0, sizeof(*dev)); memset(dev, 0, sizeof(*dev));
...@@ -395,6 +395,35 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg) ...@@ -395,6 +395,35 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
return error; return error;
} }
static __inline__ void *dev_get_idx(loff_t left)
{
struct list_head *p;
list_for_each(p, &atm_devs) {
if (!--left)
break;
}
return (p != &atm_devs) ? p : NULL;
}
void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos)
{
spin_lock(&atm_dev_lock);
return *pos ? dev_get_idx(*pos) : (void *) 1;
}
void atm_dev_seq_stop(struct seq_file *seq, void *v)
{
spin_unlock(&atm_dev_lock);
}
void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
++*pos;
v = (v == (void *)1) ? atm_devs.next : ((struct list_head *)v)->next;
return (v == &atm_devs) ? NULL : v;
}
EXPORT_SYMBOL(atm_dev_register); EXPORT_SYMBOL(atm_dev_register);
EXPORT_SYMBOL(atm_dev_deregister); EXPORT_SYMBOL(atm_dev_deregister);
......
...@@ -21,6 +21,11 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg); ...@@ -21,6 +21,11 @@ int atm_dev_ioctl(unsigned int cmd, unsigned long arg);
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
void *atm_dev_seq_start(struct seq_file *seq, loff_t *pos);
void atm_dev_seq_stop(struct seq_file *seq, void *v);
void *atm_dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
int atm_proc_dev_register(struct atm_dev *dev); int atm_proc_dev_register(struct atm_dev *dev);
void atm_proc_dev_deregister(struct atm_dev *dev); void atm_proc_dev_deregister(struct atm_dev *dev);
......
...@@ -130,7 +130,6 @@ struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio ...@@ -130,7 +130,6 @@ struct sock *bt_sock_alloc(struct socket *sock, int proto, int pi_size, int prio
} }
sock_init_data(sock, sk); sock_init_data(sock, sk);
sk_set_owner(sk, THIS_MODULE);
INIT_LIST_HEAD(&bt_sk(sk)->accept_q); INIT_LIST_HEAD(&bt_sk(sk)->accept_q);
sk->sk_zapped = 0; sk->sk_zapped = 0;
......
...@@ -175,6 +175,9 @@ static int bnep_sock_create(struct socket *sock, int protocol) ...@@ -175,6 +175,9 @@ static int bnep_sock_create(struct socket *sock, int protocol)
if (!(sk = bt_sock_alloc(sock, PF_BLUETOOTH, 0, GFP_KERNEL))) if (!(sk = bt_sock_alloc(sock, PF_BLUETOOTH, 0, GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
sk_set_owner(sk, THIS_MODULE);
sock->ops = &bnep_sock_ops; sock->ops = &bnep_sock_ops;
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
......
...@@ -587,6 +587,8 @@ static int hci_sock_create(struct socket *sock, int protocol) ...@@ -587,6 +587,8 @@ static int hci_sock_create(struct socket *sock, int protocol)
if (!sk) if (!sk)
return -ENOMEM; return -ENOMEM;
sk_set_owner(sk, THIS_MODULE);
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
sk->sk_state = BT_OPEN; sk->sk_state = BT_OPEN;
......
...@@ -69,6 +69,7 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb) ...@@ -69,6 +69,7 @@ static void __br_forward(const struct net_bridge_port *to, struct sk_buff *skb)
indev = skb->dev; indev = skb->dev;
skb->dev = to->dev; skb->dev = to->dev;
skb->ip_summed = CHECKSUM_NONE;
NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev, NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
br_forward_finish); br_forward_finish);
......
...@@ -1994,26 +1994,21 @@ extern int wireless_proc_init(void); ...@@ -1994,26 +1994,21 @@ extern int wireless_proc_init(void);
static int __init dev_proc_init(void) static int __init dev_proc_init(void)
{ {
struct proc_dir_entry *p;
int rc = -ENOMEM; int rc = -ENOMEM;
p = create_proc_entry("dev", S_IRUGO, proc_net); if (!proc_net_fops_create("dev", S_IRUGO, &dev_seq_fops))
if (!p)
goto out; goto out;
p->proc_fops = &dev_seq_fops; if (!proc_net_fops_create("softnet_stat", S_IRUGO, &softnet_seq_fops))
p = create_proc_entry("softnet_stat", S_IRUGO, proc_net);
if (!p)
goto out_dev; goto out_dev;
p->proc_fops = &softnet_seq_fops;
if (wireless_proc_init()) if (wireless_proc_init())
goto out_softnet; goto out_softnet;
rc = 0; rc = 0;
out: out:
return rc; return rc;
out_softnet: out_softnet:
remove_proc_entry("softnet_stat", proc_net); proc_net_remove("softnet_stat");
out_dev: out_dev:
remove_proc_entry("dev", proc_net); proc_net_remove("dev");
goto out; goto out;
} }
#else #else
...@@ -2759,7 +2754,6 @@ static void netdev_wait_allrefs(struct net_device *dev) ...@@ -2759,7 +2754,6 @@ static void netdev_wait_allrefs(struct net_device *dev)
current->state = TASK_INTERRUPTIBLE; current->state = TASK_INTERRUPTIBLE;
schedule_timeout(HZ / 4); schedule_timeout(HZ / 4);
current->state = TASK_RUNNING;
if (time_after(jiffies, warning_time + 10 * HZ)) { if (time_after(jiffies, warning_time + 10 * HZ)) {
printk(KERN_EMERG "unregister_netdevice: " printk(KERN_EMERG "unregister_netdevice: "
......
...@@ -1416,14 +1416,9 @@ static struct file_operations arp_seq_fops = { ...@@ -1416,14 +1416,9 @@ static struct file_operations arp_seq_fops = {
static int __init arp_proc_init(void) static int __init arp_proc_init(void)
{ {
int rc = 0; if (!proc_net_fops_create("arp", S_IRUGO, &arp_seq_fops))
struct proc_dir_entry *p = create_proc_entry("arp", S_IRUGO, proc_net); return -ENOMEM;
return 0;
if (p)
p->proc_fops = &arp_seq_fops;
else
rc = -ENOMEM;
return rc;
} }
#else /* CONFIG_PROC_FS */ #else /* CONFIG_PROC_FS */
......
...@@ -1096,19 +1096,13 @@ static struct file_operations fib_seq_fops = { ...@@ -1096,19 +1096,13 @@ static struct file_operations fib_seq_fops = {
int __init fib_proc_init(void) int __init fib_proc_init(void)
{ {
struct proc_dir_entry *p; if (!proc_net_fops_create("route", S_IRUGO, &fib_seq_fops))
int rc = 0; return -ENOMEM;
return 0;
p = create_proc_entry("route", S_IRUGO, proc_net);
if (p)
p->proc_fops = &fib_seq_fops;
else
rc = -ENOMEM;
return rc;
} }
void __init fib_proc_exit(void) void __init fib_proc_exit(void)
{ {
remove_proc_entry("route", proc_net); proc_net_remove("route");
} }
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
...@@ -669,7 +669,7 @@ static void icmp_unreach(struct sk_buff *skb) ...@@ -669,7 +669,7 @@ static void icmp_unreach(struct sk_buff *skb)
printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP " printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP "
"type %u, code %u " "type %u, code %u "
"error to a broadcast: %u.%u.%u.%u on %s\n", "error to a broadcast: %u.%u.%u.%u on %s\n",
NIPQUAD(iph->saddr), NIPQUAD(skb->nh.iph->saddr),
icmph->type, icmph->code, icmph->type, icmph->code,
NIPQUAD(iph->daddr), NIPQUAD(iph->daddr),
skb->dev->name); skb->dev->name);
......
...@@ -2162,7 +2162,7 @@ static struct ip_mc_list *igmp_mc_get_idx(struct seq_file *seq, loff_t pos) ...@@ -2162,7 +2162,7 @@ static struct ip_mc_list *igmp_mc_get_idx(struct seq_file *seq, loff_t pos)
static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos) static void *igmp_mc_seq_start(struct seq_file *seq, loff_t *pos)
{ {
read_lock(&dev_base_lock); read_lock(&dev_base_lock);
return *pos ? igmp_mc_get_idx(seq, *pos) : SEQ_START_TOKEN; return *pos ? igmp_mc_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
} }
static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *igmp_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
...@@ -2337,7 +2337,7 @@ static struct ip_sf_list *igmp_mcf_get_idx(struct seq_file *seq, loff_t pos) ...@@ -2337,7 +2337,7 @@ static struct ip_sf_list *igmp_mcf_get_idx(struct seq_file *seq, loff_t pos)
static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos) static void *igmp_mcf_seq_start(struct seq_file *seq, loff_t *pos)
{ {
read_lock(&dev_base_lock); read_lock(&dev_base_lock);
return *pos ? igmp_mcf_get_idx(seq, *pos) : SEQ_START_TOKEN; return *pos ? igmp_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
} }
static void *igmp_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *igmp_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
...@@ -2430,15 +2430,8 @@ static struct file_operations igmp_mcf_seq_fops = { ...@@ -2430,15 +2430,8 @@ static struct file_operations igmp_mcf_seq_fops = {
int __init igmp_mc_proc_init(void) int __init igmp_mc_proc_init(void)
{ {
struct proc_dir_entry *p; proc_net_fops_create("igmp", S_IRUGO, &igmp_mc_seq_fops);
proc_net_fops_create("mcfilter", S_IRUGO, &igmp_mcf_seq_fops);
p = create_proc_entry("igmp", S_IRUGO, proc_net);
if (p)
p->proc_fops = &igmp_mc_seq_fops;
p = create_proc_entry("mcfilter", S_IRUGO, proc_net);
if (p)
p->proc_fops = &igmp_mcf_seq_fops;
return 0; return 0;
} }
#endif #endif
......
...@@ -201,6 +201,7 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb) ...@@ -201,6 +201,7 @@ static inline int ip_local_deliver_finish(struct sk_buff *skb)
#ifdef CONFIG_NETFILTER_DEBUG #ifdef CONFIG_NETFILTER_DEBUG
nf_debug_ip_local_deliver(skb); nf_debug_ip_local_deliver(skb);
skb->nf_debug =3D 0;
#endif /*CONFIG_NETFILTER_DEBUG*/ #endif /*CONFIG_NETFILTER_DEBUG*/
__skb_pull(skb, ihl); __skb_pull(skb, ihl);
......
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
#include <linux/netfilter_ipv4/ip_nat_rule.h> #include <linux/netfilter_ipv4/ip_nat_rule.h>
MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>"); MODULE_AUTHOR("Magnus Boden <mb@ozaba.mine.nu>");
MODULE_DESCRIPTION("tfpt NAT helper"); MODULE_DESCRIPTION("tftp NAT helper");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
#define MAX_PORTS 8 #define MAX_PORTS 8
......
...@@ -130,57 +130,35 @@ masquerade_target(struct sk_buff **pskb, ...@@ -130,57 +130,35 @@ masquerade_target(struct sk_buff **pskb,
} }
static inline int static inline int
device_cmp(const struct ip_conntrack *i, void *ifindex) device_cmp(const struct ip_conntrack *i, void *_ina)
{ {
int ret; int ret = 0;
struct in_ifaddr *ina = _ina;
READ_LOCK(&masq_lock); READ_LOCK(&masq_lock);
ret = (i->nat.masq_index == (int)(long)ifindex); /* If it's masquerading out this interface with a different address,
or we don't know the new address of this interface. */
if (i->nat.masq_index == ina->ifa_dev->dev->ifindex
&& i->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != ina->ifa_address)
ret = 1;
READ_UNLOCK(&masq_lock); READ_UNLOCK(&masq_lock);
return ret; return ret;
} }
static int masq_device_event(struct notifier_block *this,
unsigned long event,
void *ptr)
{
struct net_device *dev = ptr;
if (event == NETDEV_DOWN) {
/* Device was downed. Search entire table for
conntracks which were associated with that device,
and forget them. */
IP_NF_ASSERT(dev->ifindex != 0);
ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
}
return NOTIFY_DONE;
}
static int masq_inet_event(struct notifier_block *this, static int masq_inet_event(struct notifier_block *this,
unsigned long event, unsigned long event,
void *ptr) void *ptr)
{ {
struct net_device *dev = ((struct in_ifaddr *)ptr)->ifa_dev->dev; /* For some configurations, interfaces often come back with
* the same address. If not, clean up old conntrack
if (event == NETDEV_DOWN) { * entries. */
/* IP address was deleted. Search entire table for if (event == NETDEV_UP)
conntracks which were associated with that device, ip_ct_selective_cleanup(device_cmp, ptr);
and forget them. */
IP_NF_ASSERT(dev->ifindex != 0);
ip_ct_selective_cleanup(device_cmp, (void *)(long)dev->ifindex);
}
return NOTIFY_DONE; return NOTIFY_DONE;
} }
static struct notifier_block masq_dev_notifier = {
.notifier_call = masq_device_event,
};
static struct notifier_block masq_inet_notifier = { static struct notifier_block masq_inet_notifier = {
.notifier_call = masq_inet_event, .notifier_call = masq_inet_event,
}; };
...@@ -198,12 +176,9 @@ static int __init init(void) ...@@ -198,12 +176,9 @@ static int __init init(void)
ret = ipt_register_target(&masquerade); ret = ipt_register_target(&masquerade);
if (ret == 0) { if (ret == 0)
/* Register for device down reports */
register_netdevice_notifier(&masq_dev_notifier);
/* Register IP address change reports */ /* Register IP address change reports */
register_inetaddr_notifier(&masq_inet_notifier); register_inetaddr_notifier(&masq_inet_notifier);
}
return ret; return ret;
} }
...@@ -211,7 +186,6 @@ static int __init init(void) ...@@ -211,7 +186,6 @@ static int __init init(void)
static void __exit fini(void) static void __exit fini(void)
{ {
ipt_unregister_target(&masquerade); ipt_unregister_target(&masquerade);
unregister_netdevice_notifier(&masq_dev_notifier);
unregister_inetaddr_notifier(&masq_inet_notifier); unregister_inetaddr_notifier(&masq_inet_notifier);
} }
......
...@@ -84,45 +84,34 @@ static inline struct rtable *route_reverse(struct sk_buff *skb, int local) ...@@ -84,45 +84,34 @@ static inline struct rtable *route_reverse(struct sk_buff *skb, int local)
static void send_reset(struct sk_buff *oldskb, int local) static void send_reset(struct sk_buff *oldskb, int local)
{ {
struct sk_buff *nskb; struct sk_buff *nskb;
struct tcphdr *otcph, *tcph; struct tcphdr otcph, *tcph;
struct rtable *rt; struct rtable *rt;
unsigned int otcplen;
u_int16_t tmp_port; u_int16_t tmp_port;
u_int32_t tmp_addr; u_int32_t tmp_addr;
int needs_ack; int needs_ack;
int hh_len; int hh_len;
/* IP header checks: fragment, too short. */ /* IP header checks: fragment. */
if (oldskb->nh.iph->frag_off & htons(IP_OFFSET) if (oldskb->nh.iph->frag_off & htons(IP_OFFSET))
|| oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
return; return;
otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
if (skb_copy_bits(oldskb, oldskb->nh.iph->ihl*4, if (skb_copy_bits(oldskb, oldskb->nh.iph->ihl*4,
otcph, sizeof(*otcph)) < 0) &otcph, sizeof(otcph)) < 0)
return; return;
/* No RST for RST. */ /* No RST for RST. */
if (otcph->rst) if (otcph.rst)
return;
/* Check checksum. */
if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
oldskb->nh.iph->daddr,
csum_partial((char *)otcph, otcplen, 0)) != 0)
return; return;
/* FIXME: Check checksum --RR */
if ((rt = route_reverse(oldskb, local)) == NULL) if ((rt = route_reverse(oldskb, local)) == NULL)
return; return;
hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15; hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
/* Copy skb (even if skb is about to be dropped, we can't just /* We need a linear, writeable skb. We also need to expand
clone it because there may be other things, such as tcpdump, headroom in case hh_len of incoming interface < hh_len of
interested in it). We also need to expand headroom in case outgoing interface */
hh_len of incoming interface < hh_len of outgoing interface */
nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb), nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
GFP_ATOMIC); GFP_ATOMIC);
if (!nskb) { if (!nskb) {
...@@ -163,12 +152,13 @@ static void send_reset(struct sk_buff *oldskb, int local) ...@@ -163,12 +152,13 @@ static void send_reset(struct sk_buff *oldskb, int local)
if (tcph->ack) { if (tcph->ack) {
needs_ack = 0; needs_ack = 0;
tcph->seq = otcph->ack_seq; tcph->seq = otcph.ack_seq;
tcph->ack_seq = 0; tcph->ack_seq = 0;
} else { } else {
needs_ack = 1; needs_ack = 1;
tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin tcph->ack_seq = htonl(ntohl(otcph.seq) + otcph.syn + otcph.fin
+ otcplen - (otcph->doff<<2)); + oldskb->len - oldskb->nh.iph->ihl*4
- (otcph.doff<<2));
tcph->seq = 0; tcph->seq = 0;
} }
......
...@@ -238,28 +238,21 @@ static struct file_operations netstat_seq_fops = { ...@@ -238,28 +238,21 @@ static struct file_operations netstat_seq_fops = {
int __init ip_misc_proc_init(void) int __init ip_misc_proc_init(void)
{ {
int rc = 0; int rc = 0;
struct proc_dir_entry *p;
p = create_proc_entry("netstat", S_IRUGO, proc_net); if (!proc_net_fops_create("netstat", S_IRUGO, &netstat_seq_fops))
if (!p)
goto out_netstat; goto out_netstat;
p->proc_fops = &netstat_seq_fops;
p = create_proc_entry("snmp", S_IRUGO, proc_net); if (!proc_net_fops_create("snmp", S_IRUGO, &snmp_seq_fops))
if (!p)
goto out_snmp; goto out_snmp;
p->proc_fops = &snmp_seq_fops;
p = create_proc_entry("sockstat", S_IRUGO, proc_net); if (!proc_net_fops_create("sockstat", S_IRUGO, &sockstat_seq_fops))
if (!p)
goto out_sockstat; goto out_sockstat;
p->proc_fops = &sockstat_seq_fops;
out: out:
return rc; return rc;
out_sockstat: out_sockstat:
remove_proc_entry("snmp", proc_net); proc_net_remove("snmp");
out_snmp: out_snmp:
remove_proc_entry("netstat", proc_net); proc_net_remove("netstat");
out_netstat: out_netstat:
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
......
...@@ -736,7 +736,7 @@ static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos) ...@@ -736,7 +736,7 @@ static struct sock *raw_get_idx(struct seq_file *seq, loff_t pos)
static void *raw_seq_start(struct seq_file *seq, loff_t *pos) static void *raw_seq_start(struct seq_file *seq, loff_t *pos)
{ {
read_lock(&raw_v4_lock); read_lock(&raw_v4_lock);
return *pos ? raw_get_idx(seq, *pos) : SEQ_START_TOKEN; return *pos ? raw_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
} }
static void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *raw_seq_next(struct seq_file *seq, void *v, loff_t *pos)
...@@ -831,19 +831,13 @@ static struct file_operations raw_seq_fops = { ...@@ -831,19 +831,13 @@ static struct file_operations raw_seq_fops = {
int __init raw_proc_init(void) int __init raw_proc_init(void)
{ {
struct proc_dir_entry *p; if (!proc_net_fops_create("raw", S_IRUGO, &raw_seq_fops))
int rc = 0; return -ENOMEM;
return 0;
p = create_proc_entry("raw", S_IRUGO, proc_net);
if (p)
p->proc_fops = &raw_seq_fops;
else
rc = -ENOMEM;
return rc;
} }
void __init raw_proc_exit(void) void __init raw_proc_exit(void)
{ {
remove_proc_entry("raw", proc_net); proc_net_remove("raw");
} }
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
...@@ -259,7 +259,7 @@ static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos) ...@@ -259,7 +259,7 @@ static struct rtable *rt_cache_get_idx(struct seq_file *seq, loff_t pos)
static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos) static void *rt_cache_seq_start(struct seq_file *seq, loff_t *pos)
{ {
return *pos ? rt_cache_get_idx(seq, *pos) : SEQ_START_TOKEN; return *pos ? rt_cache_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
} }
static void *rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *rt_cache_seq_next(struct seq_file *seq, void *v, loff_t *pos)
......
...@@ -2413,11 +2413,15 @@ static int tcp_seq_open(struct inode *inode, struct file *file) ...@@ -2413,11 +2413,15 @@ static int tcp_seq_open(struct inode *inode, struct file *file)
{ {
struct tcp_seq_afinfo *afinfo = PDE(inode)->data; struct tcp_seq_afinfo *afinfo = PDE(inode)->data;
struct seq_file *seq; struct seq_file *seq;
int rc = -ENOMEM; struct tcp_iter_state *s;
struct tcp_iter_state *s = kmalloc(sizeof(*s), GFP_KERNEL); int rc;
if (unlikely(afinfo == NULL))
return -EINVAL;
s = kmalloc(sizeof(*s), GFP_KERNEL);
if (!s) if (!s)
goto out; return -ENOMEM;
memset(s, 0, sizeof(*s)); memset(s, 0, sizeof(*s));
s->family = afinfo->family; s->family = afinfo->family;
s->seq_ops.start = tcp_seq_start; s->seq_ops.start = tcp_seq_start;
...@@ -2450,11 +2454,10 @@ int tcp_proc_register(struct tcp_seq_afinfo *afinfo) ...@@ -2450,11 +2454,10 @@ int tcp_proc_register(struct tcp_seq_afinfo *afinfo)
afinfo->seq_fops->llseek = seq_lseek; afinfo->seq_fops->llseek = seq_lseek;
afinfo->seq_fops->release = seq_release_private; afinfo->seq_fops->release = seq_release_private;
p = create_proc_entry(afinfo->name, S_IRUGO, proc_net); p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
if (p) { if (p)
p->data = afinfo; p->data = afinfo;
p->proc_fops = afinfo->seq_fops; else
} else
rc = -ENOMEM; rc = -ENOMEM;
return rc; return rc;
} }
...@@ -2463,7 +2466,7 @@ void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo) ...@@ -2463,7 +2466,7 @@ void tcp_proc_unregister(struct tcp_seq_afinfo *afinfo)
{ {
if (!afinfo) if (!afinfo)
return; return;
remove_proc_entry(afinfo->name, proc_net); proc_net_remove(afinfo->name);
memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops)); memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
} }
......
...@@ -1460,11 +1460,10 @@ int udp_proc_register(struct udp_seq_afinfo *afinfo) ...@@ -1460,11 +1460,10 @@ int udp_proc_register(struct udp_seq_afinfo *afinfo)
afinfo->seq_fops->llseek = seq_lseek; afinfo->seq_fops->llseek = seq_lseek;
afinfo->seq_fops->release = seq_release_private; afinfo->seq_fops->release = seq_release_private;
p = create_proc_entry(afinfo->name, S_IRUGO, proc_net); p = proc_net_fops_create(afinfo->name, S_IRUGO, afinfo->seq_fops);
if (p) { if (p)
p->data = afinfo; p->data = afinfo;
p->proc_fops = afinfo->seq_fops; else
} else
rc = -ENOMEM; rc = -ENOMEM;
return rc; return rc;
} }
...@@ -1473,7 +1472,7 @@ void udp_proc_unregister(struct udp_seq_afinfo *afinfo) ...@@ -1473,7 +1472,7 @@ void udp_proc_unregister(struct udp_seq_afinfo *afinfo)
{ {
if (!afinfo) if (!afinfo)
return; return;
remove_proc_entry(afinfo->name, proc_net); proc_net_remove(afinfo->name);
memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops)); memset(afinfo->seq_fops, 0, sizeof(*afinfo->seq_fops));
} }
......
...@@ -2149,59 +2149,65 @@ struct if6_iter_state { ...@@ -2149,59 +2149,65 @@ struct if6_iter_state {
int bucket; int bucket;
}; };
static inline struct inet6_ifaddr *if6_get_bucket(struct seq_file *seq, loff_t *pos) static struct inet6_ifaddr *if6_get_first(struct seq_file *seq)
{ {
int i;
struct inet6_ifaddr *ifa = NULL; struct inet6_ifaddr *ifa = NULL;
loff_t l = *pos;
struct if6_iter_state *state = seq->private; struct if6_iter_state *state = seq->private;
for (; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) for (state->bucket = 0; state->bucket < IN6_ADDR_HSIZE; ++state->bucket) {
for (i = 0, ifa = inet6_addr_lst[state->bucket]; ifa; ++i, ifa=ifa->lst_next) { ifa = inet6_addr_lst[state->bucket];
if (l--) if (ifa)
continue; break;
*pos = i; }
goto out; return ifa;
} }
out:
static struct inet6_ifaddr *if6_get_next(struct seq_file *seq, struct inet6_ifaddr *ifa)
{
struct if6_iter_state *state = seq->private;
ifa = ifa->lst_next;
try_again:
if (!ifa && ++state->bucket < IN6_ADDR_HSIZE) {
ifa = inet6_addr_lst[state->bucket];
goto try_again;
}
return ifa; return ifa;
} }
static struct inet6_ifaddr *if6_get_idx(struct seq_file *seq, loff_t pos)
{
struct inet6_ifaddr *ifa = if6_get_first(seq);
if (ifa)
while(pos && (ifa = if6_get_next(seq, ifa)) != NULL)
--pos;
return pos ? NULL : ifa;
}
static void *if6_seq_start(struct seq_file *seq, loff_t *pos) static void *if6_seq_start(struct seq_file *seq, loff_t *pos)
{ {
read_lock_bh(&addrconf_hash_lock); read_lock_bh(&addrconf_hash_lock);
return *pos ? if6_get_bucket(seq, pos) : SEQ_START_TOKEN; return if6_get_idx(seq, *pos);
} }
static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *if6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{ {
struct inet6_ifaddr *ifa; struct inet6_ifaddr *ifa;
struct if6_iter_state *state;
if (v == SEQ_START_TOKEN) {
ifa = if6_get_bucket(seq, pos);
goto out;
}
state = seq->private;
ifa = v;
ifa = ifa->lst_next;
if (ifa)
goto out;
if (++state->bucket >= IN6_ADDR_HSIZE)
goto out;
*pos = 0; ifa = if6_get_next(seq, v);
ifa = if6_get_bucket(seq, pos);
out:
++*pos; ++*pos;
return ifa; return ifa;
} }
static inline void if6_iface_seq_show(struct seq_file *seq, struct inet6_ifaddr *ifp) static void if6_seq_stop(struct seq_file *seq, void *v)
{ {
read_unlock_bh(&addrconf_hash_lock);
}
static int if6_seq_show(struct seq_file *seq, void *v)
{
struct inet6_ifaddr *ifp = (struct inet6_ifaddr *)v;
seq_printf(seq, seq_printf(seq,
"%04x%04x%04x%04x%04x%04x%04x%04x %02x %02x %02x %02x %8s\n", "%04x%04x%04x%04x%04x%04x%04x%04x %02x %02x %02x %02x %8s\n",
NIP6(ifp->addr), NIP6(ifp->addr),
...@@ -2210,22 +2216,9 @@ static inline void if6_iface_seq_show(struct seq_file *seq, struct inet6_ifaddr ...@@ -2210,22 +2216,9 @@ static inline void if6_iface_seq_show(struct seq_file *seq, struct inet6_ifaddr
ifp->scope, ifp->scope,
ifp->flags, ifp->flags,
ifp->idev->dev->name); ifp->idev->dev->name);
}
static int if6_seq_show(struct seq_file *seq, void *v)
{
if (v == SEQ_START_TOKEN)
return 0;
else
if6_iface_seq_show(seq, v);
return 0; return 0;
} }
static void if6_seq_stop(struct seq_file *seq, void *v)
{
read_unlock_bh(&addrconf_hash_lock);
}
static struct seq_operations if6_seq_ops = { static struct seq_operations if6_seq_ops = {
.start = if6_seq_start, .start = if6_seq_start,
.next = if6_seq_next, .next = if6_seq_next,
...@@ -2266,16 +2259,11 @@ static struct file_operations if6_fops = { ...@@ -2266,16 +2259,11 @@ static struct file_operations if6_fops = {
int __init if6_proc_init(void) int __init if6_proc_init(void)
{ {
struct proc_dir_entry *p; if (!proc_net_fops_create("if_inet6", S_IRUGO, &if6_fops))
int rc = 0; return -ENOMEM;
return 0;
p = create_proc_entry("if_inet6", S_IRUGO, proc_net);
if (p)
p->proc_fops = &if6_fops;
else
rc = -ENOMEM;
return rc;
} }
void if6_proc_exit(void) void if6_proc_exit(void)
{ {
proc_net_remove("if_inet6"); proc_net_remove("if_inet6");
......
...@@ -505,7 +505,7 @@ static struct ifacaddr6 *ac6_get_idx(struct seq_file *seq, loff_t pos) ...@@ -505,7 +505,7 @@ static struct ifacaddr6 *ac6_get_idx(struct seq_file *seq, loff_t pos)
static void *ac6_seq_start(struct seq_file *seq, loff_t *pos) static void *ac6_seq_start(struct seq_file *seq, loff_t *pos)
{ {
read_lock(&dev_base_lock); read_lock(&dev_base_lock);
return *pos ? ac6_get_idx(seq, *pos) : ac6_get_first(seq); return ac6_get_idx(seq, *pos);
} }
static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *ac6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
...@@ -581,11 +581,9 @@ static struct file_operations ac6_seq_fops = { ...@@ -581,11 +581,9 @@ static struct file_operations ac6_seq_fops = {
int __init ac6_proc_init(void) int __init ac6_proc_init(void)
{ {
struct proc_dir_entry *p; if (!proc_net_fops_create("anycast6", S_IRUGO, &ac6_seq_fops))
return -ENOMEM;
p = create_proc_entry("anycast6", S_IRUGO, proc_net);
if (p)
p->proc_fops = &ac6_seq_fops;
return 0; return 0;
} }
......
...@@ -603,7 +603,7 @@ static struct ip6_flowlabel *ip6fl_get_idx(struct seq_file *seq, loff_t pos) ...@@ -603,7 +603,7 @@ static struct ip6_flowlabel *ip6fl_get_idx(struct seq_file *seq, loff_t pos)
static void *ip6fl_seq_start(struct seq_file *seq, loff_t *pos) static void *ip6fl_seq_start(struct seq_file *seq, loff_t *pos)
{ {
read_lock_bh(&ip6_fl_lock); read_lock_bh(&ip6_fl_lock);
return *pos ? ip6fl_get_idx(seq, *pos) : SEQ_START_TOKEN; return *pos ? ip6fl_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
} }
static void *ip6fl_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *ip6fl_seq_next(struct seq_file *seq, void *v, loff_t *pos)
...@@ -695,12 +695,7 @@ static struct file_operations ip6fl_seq_fops = { ...@@ -695,12 +695,7 @@ static struct file_operations ip6fl_seq_fops = {
void ip6_flowlabel_init() void ip6_flowlabel_init()
{ {
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
struct proc_dir_entry *p; proc_net_fops_create("ip6_flowlabel", S_IRUGO, &ip6fl_seq_fops);
#endif
#ifdef CONFIG_PROC_FS
p = create_proc_entry("ip6_flowlabel", S_IRUGO, proc_net);
if (p)
p->proc_fops = &ip6fl_seq_fops;
#endif #endif
} }
......
...@@ -2119,7 +2119,7 @@ static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos) ...@@ -2119,7 +2119,7 @@ static struct ifmcaddr6 *igmp6_mc_get_idx(struct seq_file *seq, loff_t pos)
static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos) static void *igmp6_mc_seq_start(struct seq_file *seq, loff_t *pos)
{ {
read_lock(&dev_base_lock); read_lock(&dev_base_lock);
return *pos ? igmp6_mc_get_idx(seq, *pos) : igmp6_mc_get_first(seq); return igmp6_mc_get_idx(seq, *pos);
} }
static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *igmp6_mc_seq_next(struct seq_file *seq, void *v, loff_t *pos)
...@@ -2278,7 +2278,7 @@ static struct ip6_sf_list *igmp6_mcf_get_idx(struct seq_file *seq, loff_t pos) ...@@ -2278,7 +2278,7 @@ static struct ip6_sf_list *igmp6_mcf_get_idx(struct seq_file *seq, loff_t pos)
static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos) static void *igmp6_mcf_seq_start(struct seq_file *seq, loff_t *pos)
{ {
read_lock(&dev_base_lock); read_lock(&dev_base_lock);
return *pos ? igmp6_mcf_get_idx(seq, *pos) : SEQ_START_TOKEN; return *pos ? igmp6_mcf_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
} }
static void *igmp6_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *igmp6_mcf_seq_next(struct seq_file *seq, void *v, loff_t *pos)
...@@ -2378,9 +2378,6 @@ int __init igmp6_init(struct net_proto_family *ops) ...@@ -2378,9 +2378,6 @@ int __init igmp6_init(struct net_proto_family *ops)
struct ipv6_pinfo *np; struct ipv6_pinfo *np;
struct sock *sk; struct sock *sk;
int err; int err;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *p;
#endif
err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &igmp6_socket); err = sock_create(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6, &igmp6_socket);
if (err < 0) { if (err < 0) {
...@@ -2399,12 +2396,8 @@ int __init igmp6_init(struct net_proto_family *ops) ...@@ -2399,12 +2396,8 @@ int __init igmp6_init(struct net_proto_family *ops)
np->hop_limit = 1; np->hop_limit = 1;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
p = create_proc_entry("igmp6", S_IRUGO, proc_net); proc_net_fops_create("igmp6", S_IRUGO, &igmp6_mc_seq_fops);
if (p) proc_net_fops_create("mcfilter6", S_IRUGO, &igmp6_mcf_seq_fops);
p->proc_fops = &igmp6_mc_seq_fops;
p = create_proc_entry("mcfilter6", S_IRUGO, proc_net);
if (p)
p->proc_fops = &igmp6_mcf_seq_fops;
#endif #endif
return 0; return 0;
...@@ -2414,6 +2407,7 @@ void igmp6_cleanup(void) ...@@ -2414,6 +2407,7 @@ void igmp6_cleanup(void)
{ {
sock_release(igmp6_socket); sock_release(igmp6_socket);
igmp6_socket = NULL; /* for safety */ igmp6_socket = NULL; /* for safety */
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
proc_net_remove("mcfilter6"); proc_net_remove("mcfilter6");
proc_net_remove("igmp6"); proc_net_remove("igmp6");
......
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static struct proc_dir_entry *proc_net_devsnmp6; static struct proc_dir_entry *proc_net_devsnmp6;
#endif
static int fold_prot_inuse(struct proto *proto) static int fold_prot_inuse(struct proto *proto)
{ {
...@@ -58,7 +57,6 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v) ...@@ -58,7 +57,6 @@ static int sockstat6_seq_show(struct seq_file *seq, void *v)
return 0; return 0;
} }
struct snmp6_item struct snmp6_item
{ {
char *name; char *name;
...@@ -221,9 +219,7 @@ static struct file_operations snmp6_seq_fops = { ...@@ -221,9 +219,7 @@ static struct file_operations snmp6_seq_fops = {
int snmp6_register_dev(struct inet6_dev *idev) int snmp6_register_dev(struct inet6_dev *idev)
{ {
int err = -ENOMEM; int err = -ENOMEM;
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *p; struct proc_dir_entry *p;
#endif
if (!idev || !idev->dev) if (!idev || !idev->dev)
return -EINVAL; return -EINVAL;
...@@ -232,7 +228,6 @@ int snmp6_register_dev(struct inet6_dev *idev) ...@@ -232,7 +228,6 @@ int snmp6_register_dev(struct inet6_dev *idev)
__alignof__(struct icmpv6_mib)) < 0) __alignof__(struct icmpv6_mib)) < 0)
goto err_icmp; goto err_icmp;
#ifdef CONFIG_PROC_FS
if (!proc_net_devsnmp6) { if (!proc_net_devsnmp6) {
err = -ENOENT; err = -ENOENT;
goto err_proc; goto err_proc;
...@@ -244,27 +239,22 @@ int snmp6_register_dev(struct inet6_dev *idev) ...@@ -244,27 +239,22 @@ int snmp6_register_dev(struct inet6_dev *idev)
p->proc_fops = &snmp6_seq_fops; p->proc_fops = &snmp6_seq_fops;
idev->stats.proc_dir_entry = p; idev->stats.proc_dir_entry = p;
#endif
return 0; return 0;
#ifdef CONFIG_PROC_FS
err_proc: err_proc:
snmp6_mib_free((void **)idev->stats.icmpv6); snmp6_mib_free((void **)idev->stats.icmpv6);
#endif
err_icmp: err_icmp:
return err; return err;
} }
int snmp6_unregister_dev(struct inet6_dev *idev) int snmp6_unregister_dev(struct inet6_dev *idev)
{ {
#ifdef CONFIG_PROC_FS
if (!proc_net_devsnmp6) if (!proc_net_devsnmp6)
return -ENOENT; return -ENOENT;
if (!idev || !idev->stats.proc_dir_entry) if (!idev || !idev->stats.proc_dir_entry)
return -EINVAL; return -EINVAL;
remove_proc_entry(idev->stats.proc_dir_entry->name, remove_proc_entry(idev->stats.proc_dir_entry->name,
proc_net_devsnmp6); proc_net_devsnmp6);
#endif
snmp6_mib_free((void **)idev->stats.icmpv6); snmp6_mib_free((void **)idev->stats.icmpv6);
return 0; return 0;
...@@ -273,21 +263,16 @@ int snmp6_unregister_dev(struct inet6_dev *idev) ...@@ -273,21 +263,16 @@ int snmp6_unregister_dev(struct inet6_dev *idev)
int __init ipv6_misc_proc_init(void) int __init ipv6_misc_proc_init(void)
{ {
int rc = 0; int rc = 0;
struct proc_dir_entry *p;
p = create_proc_entry("snmp6", S_IRUGO, proc_net); if (!proc_net_fops_create("snmp6", S_IRUGO, &snmp6_seq_fops))
if (!p)
goto proc_snmp6_fail; goto proc_snmp6_fail;
else
p->proc_fops = &snmp6_seq_fops;
proc_net_devsnmp6 = proc_mkdir("dev_snmp6", proc_net); proc_net_devsnmp6 = proc_mkdir("dev_snmp6", proc_net);
if (!proc_net_devsnmp6) if (!proc_net_devsnmp6)
goto proc_dev_snmp6_fail; goto proc_dev_snmp6_fail;
p = create_proc_entry("sockstat6", S_IRUGO, proc_net);
if (!p) if (!proc_net_fops_create("sockstat6", S_IRUGO, &sockstat6_seq_fops))
goto proc_sockstat6_fail; goto proc_sockstat6_fail;
else
p->proc_fops = &sockstat6_seq_fops;
out: out:
return rc; return rc;
...@@ -307,3 +292,31 @@ void ipv6_misc_proc_exit(void) ...@@ -307,3 +292,31 @@ void ipv6_misc_proc_exit(void)
proc_net_remove("snmp6"); proc_net_remove("snmp6");
} }
#else /* CONFIG_PROC_FS */
int snmp6_register_dev(struct inet6_dev *idev)
{
int err = -ENOMEM;
if (!idev || !idev->dev)
return -EINVAL;
if (snmp6_mib_init((void **)idev->stats.icmpv6, sizeof(struct icmpv6_mib),
__alignof__(struct icmpv6_mib)) < 0)
goto err_icmp;
return 0;
err_icmp:
return err;
}
int snmp6_unregister_dev(struct inet6_dev *idev)
{
snmp6_mib_free((void **)idev->stats.icmpv6);
return 0;
}
#endif
...@@ -961,7 +961,7 @@ static struct sock *raw6_get_idx(struct seq_file *seq, loff_t pos) ...@@ -961,7 +961,7 @@ static struct sock *raw6_get_idx(struct seq_file *seq, loff_t pos)
static void *raw6_seq_start(struct seq_file *seq, loff_t *pos) static void *raw6_seq_start(struct seq_file *seq, loff_t *pos)
{ {
read_lock(&raw_v6_lock); read_lock(&raw_v6_lock);
return *pos ? raw6_get_idx(seq, *pos) : SEQ_START_TOKEN; return *pos ? raw6_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
} }
static void *raw6_seq_next(struct seq_file *seq, void *v, loff_t *pos) static void *raw6_seq_next(struct seq_file *seq, void *v, loff_t *pos)
...@@ -1059,12 +1059,8 @@ static struct file_operations raw6_seq_fops = { ...@@ -1059,12 +1059,8 @@ static struct file_operations raw6_seq_fops = {
int __init raw6_proc_init(void) int __init raw6_proc_init(void)
{ {
struct proc_dir_entry *p = create_proc_entry("raw6", S_IRUGO, proc_net); if (!proc_net_fops_create("raw6", S_IRUGO, &raw6_seq_fops))
if (!p)
return -ENOMEM; return -ENOMEM;
p->proc_fops = &raw6_seq_fops;
return 0; return 0;
} }
......
...@@ -2023,6 +2023,7 @@ static void get_timewait6_sock(struct seq_file *seq, ...@@ -2023,6 +2023,7 @@ static void get_timewait6_sock(struct seq_file *seq,
atomic_read(&tw->tw_refcnt), tw); atomic_read(&tw->tw_refcnt), tw);
} }
#ifdef CONFIG_PROC_FS
static int tcp6_seq_show(struct seq_file *seq, void *v) static int tcp6_seq_show(struct seq_file *seq, void *v)
{ {
struct tcp_iter_state *st; struct tcp_iter_state *st;
...@@ -2072,6 +2073,7 @@ void tcp6_proc_exit(void) ...@@ -2072,6 +2073,7 @@ void tcp6_proc_exit(void)
{ {
tcp_proc_unregister(&tcp6_seq_afinfo); tcp_proc_unregister(&tcp6_seq_afinfo);
} }
#endif
struct proto tcpv6_prot = { struct proto tcpv6_prot = {
.name = "TCPv6", .name = "TCPv6",
......
...@@ -26,7 +26,6 @@ ...@@ -26,7 +26,6 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/proc_fs.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/pkt_sched.h> #include <net/pkt_sched.h>
......
...@@ -27,7 +27,6 @@ ...@@ -27,7 +27,6 @@
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/proc_fs.h>
#include <net/sock.h> #include <net/sock.h>
#include <net/pkt_sched.h> #include <net/pkt_sched.h>
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/proc_fs.h> #include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/kmod.h> #include <linux/kmod.h>
#include <net/sock.h> #include <net/sock.h>
...@@ -1059,27 +1060,27 @@ int psched_us_per_tick = 1; ...@@ -1059,27 +1060,27 @@ int psched_us_per_tick = 1;
int psched_tick_per_us = 1; int psched_tick_per_us = 1;
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
static int psched_read_proc(char *buffer, char **start, off_t offset, static int psched_show(struct seq_file *seq, void *v)
int length, int *eof, void *data)
{ {
int len; seq_printf(seq, "%08x %08x %08x %08x\n",
len = sprintf(buffer, "%08x %08x %08x %08x\n",
psched_tick_per_us, psched_us_per_tick, psched_tick_per_us, psched_us_per_tick,
1000000, HZ); 1000000, HZ);
len -= offset; return 0;
}
if (len > length)
len = length;
if(len < 0)
len = 0;
*start = buffer + offset;
*eof = 1;
return len; static int psched_open(struct inode *inode, struct file *file)
{
return single_open(file, psched_show, PDE(inode)->data);
} }
static struct file_operations psched_fops = {
.owner = THIS_MODULE,
.open = psched_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
};
#endif #endif
#if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY #if PSCHED_CLOCK_SOURCE == PSCHED_GETTIMEOFDAY
...@@ -1250,9 +1251,7 @@ int __init pktsched_init(void) ...@@ -1250,9 +1251,7 @@ int __init pktsched_init(void)
tc_filter_init(); tc_filter_init();
#endif #endif
#ifdef CONFIG_PROC_FS proc_net_fops_create("psched", 0, &psched_fops);
create_proc_read_entry("net/psched", 0, 0, psched_read_proc, NULL);
#endif
return 0; return 0;
} }
...@@ -216,6 +216,13 @@ static void sch_atm_pop(struct atm_vcc *vcc,struct sk_buff *skb) ...@@ -216,6 +216,13 @@ static void sch_atm_pop(struct atm_vcc *vcc,struct sk_buff *skb)
tasklet_schedule(&p->task); tasklet_schedule(&p->task);
} }
static const u8 llc_oui_ip[] = {
0xaa, /* DSAP: non-ISO */
0xaa, /* SSAP: non-ISO */
0x03, /* Ctrl: Unnumbered Information Command PDU */
0x00, /* OUI: EtherType */
0x00, 0x00,
0x08, 0x00 }; /* Ethertype IP (0800) */
static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
struct rtattr **tca, unsigned long *arg) struct rtattr **tca, unsigned long *arg)
...@@ -322,11 +329,10 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent, ...@@ -322,11 +329,10 @@ static int atm_tc_change(struct Qdisc *sch, u32 classid, u32 parent,
flow->next = p->link.next; flow->next = p->link.next;
p->link.next = flow; p->link.next = flow;
flow->hdr_len = hdr_len; flow->hdr_len = hdr_len;
if (hdr) memcpy(flow->hdr,hdr,hdr_len); if (hdr)
else { memcpy(flow->hdr,hdr,hdr_len);
memcpy(flow->hdr,llc_oui,sizeof(llc_oui)); else
((u16 *) flow->hdr)[3] = htons(ETH_P_IP); memcpy(flow->hdr,llc_oui_ip,sizeof(llc_oui_ip));
}
*arg = (unsigned long) flow; *arg = (unsigned long) flow;
return 0; return 0;
err_out: err_out:
......
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
#include <asm/bitops.h> #include <asm/bitops.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/version.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/mm.h> #include <linux/mm.h>
......
...@@ -433,9 +433,9 @@ static int verify_userspi_info(struct xfrm_userspi_info *p) ...@@ -433,9 +433,9 @@ static int verify_userspi_info(struct xfrm_userspi_info *p)
case IPPROTO_COMP: case IPPROTO_COMP:
/* IPCOMP spi is 16-bits. */ /* IPCOMP spi is 16-bits. */
if (p->min >= 0x10000 || if (p->max >= 0x10000)
p->max >= 0x10000)
return -EINVAL; return -EINVAL;
break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -470,7 +470,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, void ** ...@@ -470,7 +470,7 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, void **
spin_lock_bh(&x->lock); spin_lock_bh(&x->lock);
if (x->km.state != XFRM_STATE_DEAD) { if (x->km.state != XFRM_STATE_DEAD) {
xfrm_alloc_spi(x, p->min, p->max); xfrm_alloc_spi(x, htonl(p->min), htonl(p->max));
if (x->id.spi) if (x->id.spi)
resp_skb = xfrm_state_netlink(skb, x, nlh->nlmsg_seq); resp_skb = xfrm_state_netlink(skb, x, nlh->nlmsg_seq);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment