[netfilter-cvslog] r3505 - in trunk/nfsim: . core kernelenv/include
tools
rusty at netfilter.org
rusty at netfilter.org
Tue Dec 28 04:27:00 CET 2004
Author: rusty at netfilter.org
Date: 2004-12-28 04:26:59 +0100 (Tue, 28 Dec 2004)
New Revision: 3505
Modified:
trunk/nfsim/.config.sample
trunk/nfsim/core/proc.h
trunk/nfsim/kernelenv/include/kernelenv.h
trunk/nfsim/tools/proc.c
Log:
More enhancement (mainly for proc) to allow ipt_recent.
Turn on CONFIG_IP_NF_MATCH_RECENT.
Modified: trunk/nfsim/.config.sample
===================================================================
--- trunk/nfsim/.config.sample 2004-12-27 19:49:28 UTC (rev 3504)
+++ trunk/nfsim/.config.sample 2004-12-28 03:26:59 UTC (rev 3505)
@@ -22,7 +22,7 @@
CONFIG_IP_NF_MATCH_MARK=y
CONFIG_IP_NF_MATCH_MULTIPORT=y
CONFIG_IP_NF_MATCH_TOS=y
-# CONFIG_IP_NF_MATCH_RECENT is not set
+CONFIG_IP_NF_MATCH_RECENT=y
CONFIG_IP_NF_MATCH_ECN=y
CONFIG_IP_NF_MATCH_DSCP=y
CONFIG_IP_NF_MATCH_AH_ESP=y
Modified: trunk/nfsim/core/proc.h
===================================================================
--- trunk/nfsim/core/proc.h 2004-12-27 19:49:28 UTC (rev 3504)
+++ trunk/nfsim/core/proc.h 2004-12-28 03:26:59 UTC (rev 3505)
@@ -24,8 +24,11 @@
#include <kernelenv.h>
+struct file;
typedef int (read_proc_t)(char *page, char **start, off_t off,
int count, int *eof, void *data);
+typedef int (write_proc_t)(struct file *file, const char __user *buffer,
+ unsigned long count, void *data);
typedef int (get_info_t)(char *, char **, off_t, int);
@@ -36,6 +39,9 @@
struct module *owner;
struct proc_dir_entry *next, *parent, *subdir;
struct file_operations *proc_fops;
+ void *data;
+ read_proc_t *read_proc;
+ write_proc_t *write_proc;
/* all we need is the S_IFDR flag.. */
mode_t mode;
Modified: trunk/nfsim/kernelenv/include/kernelenv.h
===================================================================
--- trunk/nfsim/kernelenv/include/kernelenv.h 2004-12-27 19:49:28 UTC (rev 3504)
+++ trunk/nfsim/kernelenv/include/kernelenv.h 2004-12-28 03:26:59 UTC (rev 3505)
@@ -44,6 +44,7 @@
#include <asm/byteorder.h>
#define smp_wmb()
+#define wmb()
#define barrier()
#define mb()
@@ -75,6 +76,17 @@
(void) (&_x == &_y); \
_x > _y ? _x : _y; })
+/*
+ * ..and if you can't take the strict
+ * types, you can specify one yourself.
+ *
+ * Or not use min/max at all, of course.
+ */
+#define min_t(type,x,y) \
+ ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; })
+#define max_t(type,x,y) \
+ ({ type __x = (x); type __y = (y); __x > __y ? __x: __y; })
+
#include <linux/list.h>
/* logging */
@@ -173,8 +185,8 @@
#define KERN_DEBUG "DEBUG:"/* debug-level messages */
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+#define ALIGN(x,a) (((x)+(a)-1)&~((a)-1))
-
/* err.h */
#define ERR_PTR(x) ((void *)(x))
#define PTR_ERR(x) ((long)(x))
@@ -775,6 +787,9 @@
#define spin_lock_bh(x) __generic_write_lock((x), __location__)
#define spin_unlock_bh(x) __generic_write_unlock((x), __location__)
+#define spin_lock_irq(x) __generic_write_lock((x), __location__)
+#define spin_unlock_irq(x) __generic_write_unlock((x), __location__)
+
#define spin_lock_irqsave(x,f) __generic_write_lock((x), __location__); f++
#define spin_unlock_irqrestore(x,f) __generic_write_unlock((x), __location__); f--
Modified: trunk/nfsim/tools/proc.c
===================================================================
--- trunk/nfsim/tools/proc.c 2004-12-27 19:49:28 UTC (rev 3504)
+++ trunk/nfsim/tools/proc.c 2004-12-28 03:26:59 UTC (rev 3505)
@@ -81,6 +81,139 @@
}
+/* Stolen straight from kernel's fs/proc/base.c,
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+/* buffer size is one page but our output routines use some slack for overruns */
+#define PROC_BLOCK_SIZE (PAGE_SIZE - 1024)
+
+static ssize_t
+proc_file_read(struct proc_dir_entry *dp, char *buf, size_t nbytes,
+ loff_t *ppos)
+{
+ ssize_t retval=0;
+ int eof=0;
+ ssize_t n, count;
+ char *start;
+ char page[PAGE_SIZE];
+
+ while ((nbytes > 0) && !eof) {
+ count = min_t(ssize_t, PROC_BLOCK_SIZE, nbytes);
+
+ start = NULL;
+ if (dp->get_info) {
+ /* Handle old net routines */
+ n = dp->get_info(page, &start, *ppos, count);
+ if (n < count)
+ eof = 1;
+ } else if (dp->read_proc) {
+ /*
+ * How to be a proc read function
+ * ------------------------------
+ * Prototype:
+ * int f(char *buffer, char **start, off_t offset,
+ * int count, int *peof, void *dat)
+ *
+ * Assume that the buffer is "count" bytes in size.
+ *
+ * If you know you have supplied all the data you
+ * have, set *peof.
+ *
+ * You have three ways to return data:
+ * 0) Leave *start = NULL. (This is the default.)
+ * Put the data of the requested offset at that
+ * offset within the buffer. Return the number (n)
+ * of bytes there are from the beginning of the
+ * buffer up to the last byte of data. If the
+ * number of supplied bytes (= n - offset) is
+ * greater than zero and you didn't signal eof
+ * and the reader is prepared to take more data
+ * you will be called again with the requested
+ * offset advanced by the number of bytes
+ * absorbed. This interface is useful for files
+ * no larger than the buffer.
+ * 1) Set *start = an unsigned long value less than
+ * the buffer address but greater than zero.
+ * Put the data of the requested offset at the
+ * beginning of the buffer. Return the number of
+ * bytes of data placed there. If this number is
+ * greater than zero and you didn't signal eof
+ * and the reader is prepared to take more data
+ * you will be called again with the requested
+ * offset advanced by *start. This interface is
+ * useful when you have a large file consisting
+ * of a series of blocks which you want to count
+ * and return as wholes.
+ * (Hack by Paul.Russell at rustcorp.com.au)
+ * 2) Set *start = an address within the buffer.
+ * Put the data of the requested offset at *start.
+ * Return the number of bytes of data placed there.
+ * If this number is greater than zero and you
+ * didn't signal eof and the reader is prepared to
+ * take more data you will be called again with the
+ * requested offset advanced by the number of bytes
+ * absorbed.
+ */
+ n = dp->read_proc(page, &start, *ppos,
+ count, &eof, dp->data);
+ } else
+ break;
+
+ if (n == 0) /* end of file */
+ break;
+ if (n < 0) { /* error */
+ if (retval == 0)
+ retval = n;
+ break;
+ }
+
+ if (start == NULL) {
+ if (n > PAGE_SIZE) {
+ printk(KERN_ERR
+ "proc_file_read: Apparent buffer overflow!\n");
+ n = PAGE_SIZE;
+ }
+ n -= *ppos;
+ if (n <= 0)
+ break;
+ if (n > count)
+ n = count;
+ start = page + *ppos;
+ } else if (start < page) {
+ if (n > PAGE_SIZE) {
+ printk(KERN_ERR
+ "proc_file_read: Apparent buffer overflow!\n");
+ n = PAGE_SIZE;
+ }
+ if (n > count) {
+ /*
+ * Don't reduce n because doing so might
+ * cut off part of a data block.
+ */
+ printk(KERN_WARNING
+ "proc_file_read: Read count exceeded\n");
+ }
+ } else /* start >= page */ {
+ unsigned long startoff = (unsigned long)(start - page);
+ if (n > (PAGE_SIZE - startoff)) {
+ printk(KERN_ERR
+ "proc_file_read: Apparent buffer overflow!\n");
+ n = PAGE_SIZE - startoff;
+ }
+ if (n > count)
+ n = count;
+ }
+
+ memcpy(buf, start < page ? page : start, n);
+
+ *ppos += start < page ? (unsigned long)start : n;
+ nbytes -= n;
+ buf += n;
+ retval += n;
+ }
+ return retval;
+}
+
static int proc_cat(const char *name)
{
struct proc_dir_entry *dir;
@@ -103,11 +236,18 @@
start = 0;
offset = 0;
memset(buf, 0, 4096);
- if (dir->get_info) {
- (*dir->get_info)(buf, &start, offset, 4096);
- printk("%s", buf);
+ if (!dir->proc_fops) {
+ int len;
+
+ offset = 0;
+ len = proc_file_read(dir, buf, 4096, &offset);
+ if (len < 0)
+ nfsim_log(LOG_ALWAYS, "proc entry %s read failed %i!",
+ name, len);
+ else
+ printk("%.*s", len, buf);
return 0;
- } else if (dir->proc_fops) {
+ } else {
struct file file;
int ret;
More information about the netfilter-cvslog
mailing list