[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