From: Mike Baker Date: Sat, 31 Jul 2004 07:30:57 +0000 (+0000) Subject: restructure; cleanup X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=214d560052367e0e7b5f3fafff469f0833123890;p=librecmc%2Flibrecmc.git restructure; cleanup SVN-Revision: 120 --- diff --git a/obsolete-buildroot/make/busybox.mk b/obsolete-buildroot/make/busybox.mk index 510489de39..baeb952667 100644 --- a/obsolete-buildroot/make/busybox.mk +++ b/obsolete-buildroot/make/busybox.mk @@ -15,7 +15,7 @@ BUSYBOX_SOURCE:=busybox-1.00-pre8.tar.bz2 BUSYBOX_SITE:=http://www.busybox.net/downloads endif BUSYBOX_UNZIP=bzcat -BUSYBOX_CONFIG:=$(SOURCE_DIR)/busybox.config +BUSYBOX_CONFIG:=$(SOURCE_DIR)/openwrt/busybox/busybox.config $(DL_DIR)/$(BUSYBOX_SOURCE): $(WGET) -P $(DL_DIR) $(BUSYBOX_SITE)/$(BUSYBOX_SOURCE) @@ -25,7 +25,7 @@ busybox-source: $(DL_DIR)/$(BUSYBOX_SOURCE) $(BUSYBOX_CONFIG) $(BUSYBOX_DIR)/.configured: $(DL_DIR)/$(BUSYBOX_SOURCE) $(BUSYBOX_CONFIG) $(BUSYBOX_UNZIP) $(DL_DIR)/$(BUSYBOX_SOURCE) | tar -C $(BUILD_DIR) -xvf - # Allow busybox patches. - $(SOURCE_DIR)/patch-kernel.sh $(BUSYBOX_DIR) $(SOURCE_DIR) busybox-*.patch + $(SOURCE_DIR)/patch-kernel.sh $(BUSYBOX_DIR) $(SOURCE_DIR)/openwrt/busybox/patches cp $(BUSYBOX_CONFIG) $(BUSYBOX_DIR)/.config $(SED) "s,^CROSS.*,CROSS=$(TARGET_CROSS)\n\ PREFIX=$(TARGET_DIR),;" $(BUSYBOX_DIR)/Rules.mak diff --git a/obsolete-buildroot/make/openssh.mk b/obsolete-buildroot/make/openssh.mk index 7fdb73ed0a..6c5ba7a4e2 100644 --- a/obsolete-buildroot/make/openssh.mk +++ b/obsolete-buildroot/make/openssh.mk @@ -93,15 +93,15 @@ $(OPENSSH_IPK_DIR)/usr/bin/ssh: $(OPENSSH_DIR)/ssh $(OPENSSH_SERVER_IPK): $(OPENSSH_IPK_DIR)/usr/bin/ssh rm -rf $(OPENSSH_IPK_DIR)/build mkdir -p $(OPENSSH_IPK_DIR)/build/CONTROL - cp $(SOURCE_DIR)/openssh.server.control $(OPENSSH_IPK_DIR)/build/CONTROL/control - cp $(SOURCE_DIR)/openssh.server.conffiles $(OPENSSH_IPK_DIR)/build/CONTROL/conffiles - cp $(SOURCE_DIR)/openssh.server.preinst $(OPENSSH_IPK_DIR)/build/CONTROL/preinst + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.server.control $(OPENSSH_IPK_DIR)/build/CONTROL/control + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.server.conffiles $(OPENSSH_IPK_DIR)/build/CONTROL/conffiles + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.server.preinst $(OPENSSH_IPK_DIR)/build/CONTROL/preinst chmod a+x $(OPENSSH_IPK_DIR)/build/CONTROL/preinst - cp $(SOURCE_DIR)/openssh.server.postinst $(OPENSSH_IPK_DIR)/build/CONTROL/postinst + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.server.postinst $(OPENSSH_IPK_DIR)/build/CONTROL/postinst chmod a+x $(OPENSSH_IPK_DIR)/build/CONTROL/postinst mkdir -p $(OPENSSH_IPK_DIR)/build/etc/init.d - cp $(SOURCE_DIR)/openssh.server.sshd_config $(OPENSSH_IPK_DIR)/build/etc/sshd_config - cp $(SOURCE_DIR)/openssh.server.S50sshd-ipk $(OPENSSH_IPK_DIR)/build/etc/init.d/S50sshd + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.server.sshd_config $(OPENSSH_IPK_DIR)/build/etc/sshd_config + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.server.S50sshd-ipk $(OPENSSH_IPK_DIR)/build/etc/init.d/S50sshd chmod a+x $(OPENSSH_IPK_DIR)/build/etc/init.d/S50sshd mkdir -p $(OPENSSH_IPK_DIR)/build/usr/sbin cp $(OPENSSH_IPK_DIR)/usr/sbin/sshd $(OPENSSH_IPK_DIR)/build/usr/sbin @@ -113,12 +113,12 @@ $(OPENSSH_SERVER_IPK): $(OPENSSH_IPK_DIR)/usr/bin/ssh $(OPENSSH_CLIENT_IPK): $(OPENSSH_IPK_DIR)/usr/bin/ssh rm -rf $(OPENSSH_IPK_DIR)/build mkdir -p $(OPENSSH_IPK_DIR)/build/CONTROL - cp $(SOURCE_DIR)/openssh.client.control $(OPENSSH_IPK_DIR)/build/CONTROL/control - cp $(SOURCE_DIR)/openssh.client.conffiles $(OPENSSH_IPK_DIR)/build/CONTROL/conffiles - cp $(SOURCE_DIR)/openssh.client.preinst $(OPENSSH_IPK_DIR)/build/CONTROL/preinst + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.client.control $(OPENSSH_IPK_DIR)/build/CONTROL/control + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.client.conffiles $(OPENSSH_IPK_DIR)/build/CONTROL/conffiles + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.client.preinst $(OPENSSH_IPK_DIR)/build/CONTROL/preinst chmod a+x $(OPENSSH_IPK_DIR)/build/CONTROL/preinst mkdir -p $(OPENSSH_IPK_DIR)/build/etc - cp $(SOURCE_DIR)/openssh.client.ssh_config $(OPENSSH_IPK_DIR)/build/etc/ssh_config + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.client.ssh_config $(OPENSSH_IPK_DIR)/build/etc/ssh_config mkdir -p $(OPENSSH_IPK_DIR)/build/usr/bin cp $(OPENSSH_IPK_DIR)/usr/bin/ssh $(OPENSSH_IPK_DIR)/build/usr/bin cp $(OPENSSH_IPK_DIR)/usr/bin/scp $(OPENSSH_IPK_DIR)/build/usr/bin @@ -128,7 +128,7 @@ $(OPENSSH_CLIENT_IPK): $(OPENSSH_IPK_DIR)/usr/bin/ssh $(OPENSSH_SFTP_SERVER_IPK): $(OPENSSH_IPK_DIR)/usr/bin/ssh rm -rf $(OPENSSH_IPK_DIR)/build mkdir -p $(OPENSSH_IPK_DIR)/build/CONTROL - cp $(SOURCE_DIR)/openssh.sftp-server.control $(OPENSSH_IPK_DIR)/build/CONTROL/control + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.sftp-server.control $(OPENSSH_IPK_DIR)/build/CONTROL/control mkdir -p $(OPENSSH_IPK_DIR)/build/usr/sbin cp $(OPENSSH_IPK_DIR)/usr/sbin/sftp-server $(OPENSSH_IPK_DIR)/build/usr/sbin cd $(BUILD_DIR); $(STAGING_DIR)/bin/ipkg-build -c -o root -g root $(OPENSSH_IPK_DIR)/build @@ -137,7 +137,7 @@ $(OPENSSH_SFTP_SERVER_IPK): $(OPENSSH_IPK_DIR)/usr/bin/ssh $(OPENSSH_SFTP_CLIENT_IPK): $(OPENSSH_IPK_DIR)/usr/bin/ssh rm -rf $(OPENSSH_IPK_DIR)/build mkdir -p $(OPENSSH_IPK_DIR)/build/CONTROL - cp $(SOURCE_DIR)/openssh.sftp-client.control $(OPENSSH_IPK_DIR)/build/CONTROL/control + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.sftp-client.control $(OPENSSH_IPK_DIR)/build/CONTROL/control mkdir -p $(OPENSSH_IPK_DIR)/build/usr/bin cp $(OPENSSH_IPK_DIR)/usr/bin/sftp $(OPENSSH_IPK_DIR)/build/usr/bin cd $(BUILD_DIR); $(STAGING_DIR)/bin/ipkg-build -c -o root -g root $(OPENSSH_IPK_DIR)/build @@ -146,7 +146,7 @@ $(OPENSSH_SFTP_CLIENT_IPK): $(OPENSSH_IPK_DIR)/usr/bin/ssh $(OPENSSH_CLIENT_EX_IPK): $(OPENSSH_IPK_DIR)/usr/bin/ssh rm -rf $(OPENSSH_IPK_DIR)/build mkdir -p $(OPENSSH_IPK_DIR)/build/CONTROL - cp $(SOURCE_DIR)/openssh.client.ex.control $(OPENSSH_IPK_DIR)/build/CONTROL/control + cp $(SOURCE_DIR)/openwrt/ipkg/openssh/openssh.client.ex.control $(OPENSSH_IPK_DIR)/build/CONTROL/control mkdir -p $(OPENSSH_IPK_DIR)/build/usr/bin cp $(OPENSSH_IPK_DIR)/usr/bin/ssh-add $(OPENSSH_IPK_DIR)/build/usr/bin cp $(OPENSSH_IPK_DIR)/usr/bin/ssh-agent $(OPENSSH_IPK_DIR)/build/usr/bin diff --git a/obsolete-buildroot/make/openssl.mk b/obsolete-buildroot/make/openssl.mk index e20c8b9d63..3fa273f5b8 100644 --- a/obsolete-buildroot/make/openssl.mk +++ b/obsolete-buildroot/make/openssl.mk @@ -70,7 +70,7 @@ openssl: uclibc $(TARGET_DIR)/usr/lib/libcrypto.so.0.9.7 $(LIBSSL_IPK): uclibc $(STAGING_DIR)/usr/lib/libcrypto.a mkdir -p $(OPENSSL_IPK_DIR)/CONTROL - cp $(SOURCE_DIR)/libssl.control $(OPENSSL_IPK_DIR)/CONTROL/control + cp $(SOURCE_DIR)/openwrt/openssl/control $(OPENSSL_IPK_DIR)/CONTROL/control mkdir -p $(OPENSSL_IPK_DIR)/usr/lib cp -fa $(STAGING_DIR)/lib/libcrypto.so* $(OPENSSL_IPK_DIR)/usr/lib/ cp -fa $(STAGING_DIR)/lib/libssl.so* $(OPENSSL_IPK_DIR)/usr/lib/ diff --git a/obsolete-buildroot/make/openwrt.mk b/obsolete-buildroot/make/openwrt.mk index 6889e1ec56..e839a0a5cb 100644 --- a/obsolete-buildroot/make/openwrt.mk +++ b/obsolete-buildroot/make/openwrt.mk @@ -36,22 +36,10 @@ openwrt-base: $(OPENWRT_TARGETS) ifneq ($(filter $(TARGETS),openwrt-base),) -# WRT54G_SOURCE=wrt54gv2.2.02.2.tgz -# WRT54G_SITE=http://www.linksys.com/support/opensourcecode/wrt54gv2/2.02.2 - -# WRT54G_SOURCE=wrt54g.2.02.7.tgz -# WRT54G_SITE=http://www.linksys.com/support/opensourcecode/wrt54gv2/2.02.7 -# WRT54G_DIR=$(BUILD_DIR)/WRT54G - WRT54G_SOURCE=wrt54gs.2.07.1.tgz WRT54G_SITE=http://www.linksys.com/support/opensourcecode/wrt54gs/2.07.1 - WRT54G_DIR=$(BUILD_DIR)/WRT54GS -# OPENWRT_ROOT=openwrt-root.tar.bz2 -# OPENWRT_SITE=http://127.0.0.1 -# OPENWRT_DIR=$(BUILD_DIR)/openwrt - LINUX_DIR=$(WRT54G_DIR)/release/src/linux/linux LINUX_FORMAT=zImage LINUX_BINLOC=arch/mips/brcm-boards/bcm947xx/compressed/vmlinuz @@ -63,17 +51,14 @@ $(LINUX_DIR)/.unpacked: $(WRT54G_DIR)/.prepared touch $(LINUX_DIR)/.unpacked $(LINUX_DIR)/.patched: $(WRT54G_DIR)/.prepared - $(SOURCE_DIR)/patch-kernel.sh $(LINUX_DIR)/../.. $(SOURCE_DIR) openwrt-linux-netfilter.patch - $(SOURCE_DIR)/patch-kernel.sh $(LINUX_DIR)/../.. $(SOURCE_DIR) openwrt-linux-sch_htb.patch - $(SOURCE_DIR)/patch-kernel.sh $(LINUX_DIR)/../.. $(SOURCE_DIR) openwrt-wrt54g-linux.patch - $(SOURCE_DIR)/patch-kernel.sh $(LINUX_DIR)/../.. $(SOURCE_DIR) openwrt-wrt54g-nfsswap.patch + $(SOURCE_DIR)/patch-kernel.sh $(LINUX_DIR)/../.. $(SOURCE_DIR)/openwrt/kernel/patches # use replacement diag module code - cp -f $(SOURCE_DIR)/openwrt-diag.c $(LINUX_DIR)/drivers/net/diag/diag_led.c - cp -f $(SOURCE_DIR)/openwrt-wrt54g-linux.config $(LINUX_DIR)/.config + cp -f $(SOURCE_DIR)/openwrt/kernel/diag.c $(LINUX_DIR)/drivers/net/diag/diag_led.c + cp -f $(SOURCE_DIR)/openwrt/kernel/linux.config $(LINUX_DIR)/.config -(cd $(BUILD_DIR); ln -sf $(LINUX_DIR) linux) -(cd $(LINUX_DIR)/arch/mips/brcm-boards/bcm947xx/; \ rm -rf compressed; \ - tar jxvf $(SOURCE_DIR)/compressed-20040531.tar.bz2; \ + tar jxvf $(SOURCE_DIR)/openwrt/kernel/compressed-20040531.tar.bz2; \ ) touch $(LINUX_DIR)/.patched @@ -107,8 +92,7 @@ $(WRT54G_DIR)/.source: $(DL_DIR)/$(WRT54G_SOURCE) touch $(WRT54G_DIR)/.source $(WRT54G_DIR)/.prepared: $(WRT54G_DIR)/.source - $(SOURCE_DIR)/patch-kernel.sh $(WRT54G_DIR) $(SOURCE_DIR) openwrt-wrt54g-router.patch - $(SOURCE_DIR)/patch-kernel.sh $(WRT54G_DIR) $(SOURCE_DIR) openwrt-wrt54g-shared.patch + $(SOURCE_DIR)/patch-kernel.sh $(WRT54G_DIR) $(SOURCE_DIR)/openwrt/patches touch $(WRT54G_DIR)/.prepared ###################################################################### @@ -236,8 +220,8 @@ openwrt-prune: ###################################################################### wrt-tools: - $(CC) -o $(WRT54G_DIR)/release/tools/trx $(SOURCE_DIR)/trx.c - $(CC) -o $(WRT54G_DIR)/release/tools/addpattern $(SOURCE_DIR)/addpattern.c + $(CC) -o $(WRT54G_DIR)/release/tools/trx $(SOURCE_DIR)/openwrt/tools/trx.c + $(CC) -o $(WRT54G_DIR)/release/tools/addpattern $(SOURCE_DIR)/openwrt/tools/addpattern.c openwrt-linux.trx: openwrt-prune squashfsroot wrt-tools $(WRT54G_DIR)/release/tools/trx -o openwrt-linux.trx \ @@ -253,24 +237,4 @@ openwrt-g-code.bin: openwrt-gs-code.bin openwrt-code.bin: openwrt-gs-code.bin openwrt-g-code.bin ###################################################################### - -openwrt-sourceball: - tar cjf buildroot-openwrt.tar.bz2 \ - README.openwrt \ - Makefile \ - Makefile-openwrt \ - make/openwrt.mk \ - make/uclibc.mk \ - make/busybox.mk \ - sources/uClibc.config \ - sources/uClibc.config-openwrt \ - sources/busybox-openwrt-*.patch \ - sources/busybox.config \ - sources/busybox.config-openwrt \ - sources/dnsmasq1-openwrt.patch \ - sources/iptables-openwrt-extensions.patch \ - sources/openwrt-wrt54g-linux.config \ - sources/openwrt-wrt54g-*.patch \ - sources/openwrt-diag.c - endif diff --git a/obsolete-buildroot/make/zlib.mk b/obsolete-buildroot/make/zlib.mk index 5500fec87a..48e7b32569 100644 --- a/obsolete-buildroot/make/zlib.mk +++ b/obsolete-buildroot/make/zlib.mk @@ -66,7 +66,7 @@ zlib: uclibc $(TARGET_DIR)/lib/libz.so.1.1.4 $(ZLIB_IPK): uclibc $(STAGING_DIR)/lib/libz.so.1.1.4 mkdir -p $(ZLIB_IPK_DIR)/CONTROL - cp $(SOURCE_DIR)/zlib.control $(ZLIB_IPK_DIR)/CONTROL/control + cp $(SOURCE_DIR)/openwrt/ipkg/zlib/control $(ZLIB_IPK_DIR)/CONTROL/control mkdir -p $(ZLIB_IPK_DIR)/lib cp -dpf $(STAGING_DIR)/lib/libz.so* $(ZLIB_IPK_DIR)/lib; -$(STRIP) --strip-unneeded $(ZLIB_IPK_DIR)/lib/libz.so* diff --git a/obsolete-buildroot/sources/addpattern.c b/obsolete-buildroot/sources/addpattern.c deleted file mode 100644 index dbf8ed690e..0000000000 --- a/obsolete-buildroot/sources/addpattern.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright (C) 2004 Manuel Novoa III - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* July 29, 2004 - * - * This is a hacked replacement for the 'addpattern' utility used to - * create wrt54g .bin firmware files. It isn't pretty, but it does - * the job for me. - * - * Extensions: - * -v allows setting the version string on the command line. - * -{0|1} sets the (currently ignored) hw_ver flag in the header - * to 0 or 1 respectively. - */ - -#include -#include -#include -#include -#include -#include - -/**********************************************************************/ - -#define CODE_ID "U2ND" /* from code_pattern.h */ -#define CODE_PATTERN "W54S" /* from code_pattern.h */ - -#define CYBERTAN_VERSION "v2.07.1" /* from cyutils.h */ -/* #define CYBERTAN_VERSION "v2.04.3" */ - -struct code_header { /* from cyutils.h */ - char magic[4]; - char res1[4]; /* for extra magic */ - char fwdate[3]; - char fwvern[3]; - char id[4]; /* U2ND */ -#if 0 - unsigned char res2[14]; -#else - char hw_ver; /* 0: for 4702, 1: for 4712 -- new in 2.04.3 */ - unsigned char res2[13]; -#endif -} ; - -/**********************************************************************/ - -void usage(void) __attribute__ (( __noreturn__ )); - -void usage(void) -{ - fprintf(stderr, "Usage: addpattern [-i trxfile] [-o binfile] [-p pattern] [-g] [-v v#.#.#] [-{0|1}]\n"); - exit(EXIT_FAILURE); -} - -int main(int argc, char **argv) -{ - char buf[1024]; /* keep this at 1k or adjust garbage calc below */ - struct code_header *hdr; - FILE *in = stdin; - FILE *out = stdout; - char *ifn = NULL; - char *ofn = NULL; - char *pattern = CODE_PATTERN; - char *version = CYBERTAN_VERSION; - int gflag = 0; - int c; - int v0, v1, v2; - size_t off, n; - time_t t; - struct tm *ptm; - - fprintf(stderr, "mjn3's addpattern replacement - v0.80\n"); - - hdr = (struct code_header *) buf; - - while ((c = getopt(argc, argv, "i:o:p:gv:01")) != -1) { - switch (c) { - case 'i': - ifn = optarg; - break; - case 'o': - ofn = optarg; - break; - case 'p': - pattern = optarg; - break; - case 'g': - gflag = 1; - break; - case 'v': /* extension to allow setting version */ - version = optarg; - break; - case '0': - hdr->hw_ver = 0; - break; - case '1': - hdr->hw_ver = 1; - break; - default: - usage(); - } - } - - if (optind != argc) { - fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); - usage(); - } - - if (strlen(pattern) != 4) { - fprintf(stderr, "illegal pattern \"%s\": length != 4\n", pattern); - usage(); - } - - if (ifn && !(in = fopen(ifn, "r"))) { - fprintf(stderr, "can not open \"%s\" for reading\n", ifn); - usage(); - } - - if (ofn && !(out = fopen(ofn, "w"))) { - fprintf(stderr, "can not open \"%s\" for writing\n", ofn); - usage(); - } - - if (time(&t) == (time_t)(-1)) { - fprintf(stderr, "time call failed\n"); - return EXIT_FAILURE; - } - - ptm = localtime(&t); - - if (3 != sscanf(version, "v%d.%d.%d", &v0, &v1, &v2)) { - fprintf(stderr, "bad version string \"%s\"\n", version); - return EXIT_FAILURE; - } - - memset(hdr, 0, sizeof(struct code_header)); - memcpy(&hdr->magic, pattern, 4); - hdr->fwdate[0] = ptm->tm_year % 100; - hdr->fwdate[1] = ptm->tm_mon + 1; - hdr->fwdate[2] = ptm->tm_mday; - hdr->fwvern[0] = v0; - hdr->fwvern[1] = v1; - hdr->fwvern[2] = v2; - memcpy(&hdr->id, CODE_ID, strlen(CODE_ID)); - - off = sizeof(struct code_header); - - fprintf(stderr, "writing firmware v%d.%d.%d on %d/%d/%d (y/m/d)\n", - v0, v1, v2, - hdr->fwdate[0], hdr->fwdate[1], hdr->fwdate[2]); - - - while ((n = fread(buf + off, 1, sizeof(buf)-off, in) + off) > 0) { - off = 0; - if (n < sizeof(buf)) { - if (ferror(in)) { - FREAD_ERROR: - fprintf(stderr, "fread error\n"); - return EXIT_FAILURE; - } - if (gflag) { - gflag = sizeof(buf) - n; - memset(buf + n, 0xff, gflag); - fprintf(stderr, "adding %d bytes of garbage\n", gflag); - n = sizeof(buf); - } - } - if (!fwrite(buf, n, 1, out)) { - FWRITE_ERROR: - fprintf(stderr, "fwrite error\n"); - return EXIT_FAILURE; - } - } - - if (ferror(in)) { - goto FREAD_ERROR; - } - - if (fflush(out)) { - goto FWRITE_ERROR; - } - - fclose(in); - fclose(out); - - return EXIT_SUCCESS; -} diff --git a/obsolete-buildroot/sources/busybox-openwrt-100-killall5.patch b/obsolete-buildroot/sources/busybox-openwrt-100-killall5.patch deleted file mode 100644 index 161b7e6f25..0000000000 --- a/obsolete-buildroot/sources/busybox-openwrt-100-killall5.patch +++ /dev/null @@ -1,87 +0,0 @@ -diff -urN busybox-dist/include/applets.h busybox/include/applets.h ---- busybox-dist/include/applets.h 2004-03-13 02:33:09.000000000 -0600 -+++ busybox/include/applets.h 2004-03-16 09:45:29.000000000 -0600 -@@ -313,6 +313,9 @@ - #ifdef CONFIG_KILLALL - APPLET(killall, kill_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) - #endif -+#ifdef CONFIG_KILLALL5 -+ APPLET(killall5, kill_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) -+#endif - #ifdef CONFIG_KLOGD - APPLET(klogd, klogd_main, _BB_DIR_SBIN, _BB_SUID_NEVER) - #endif -diff -urN busybox-dist/include/usage.h busybox/include/usage.h ---- busybox-dist/include/usage.h 2004-03-13 02:33:09.000000000 -0600 -+++ busybox/include/usage.h 2004-03-16 09:45:29.000000000 -0600 -@@ -1389,6 +1389,13 @@ - #define killall_example_usage \ - "$ killall apache\n" - -+#define killall5_trivial_usage \ -+ "" -+#define killall5_full_usage \ -+ "" -+#define killall5_example_usage \ -+ "" -+ - #define klogd_trivial_usage \ - "[-c n] [-n]" - #define klogd_full_usage \ -diff -urN busybox-dist/procps/Config.in busybox/procps/Config.in ---- busybox-dist/procps/Config.in 2003-12-24 00:02:11.000000000 -0600 -+++ busybox/procps/Config.in 2004-03-16 09:45:29.000000000 -0600 -@@ -30,6 +30,11 @@ - specified commands. If no signal name is specified, SIGTERM is - sent. - -+config CONFIG_KILLALL5 -+ bool "killall5" -+ default n -+ depends on CONFIG_KILL -+ - config CONFIG_PIDOF - bool "pidof" - default n -diff -urN busybox-dist/procps/kill.c busybox/procps/kill.c ---- busybox-dist/procps/kill.c 2004-03-15 02:29:03.000000000 -0600 -+++ busybox/procps/kill.c 2004-03-16 09:45:29.000000000 -0600 -@@ -34,6 +34,7 @@ - - #define KILL 0 - #define KILLALL 1 -+#define KILLALL5 2 - - extern int kill_main(int argc, char **argv) - { -@@ -47,6 +48,9 @@ - #else - whichApp = KILL; - #endif -+#ifdef CONFIG_KILLALL5 -+ whichApp = (strcmp(bb_applet_name, "killall5") == 0)? KILLALL5 : whichApp; -+#endif - - /* Parse any options */ - if (argc < 2) -@@ -119,6 +123,20 @@ - } - - } -+#ifdef CONFIG_KILLALL5 -+ else if (whichApp == KILLALL5) { -+ procps_status_t * p; -+ pid_t myPid=getpid(); -+ while ((p = procps_scan(0)) != 0) { -+ if (p->pid != 1 && p->pid != myPid && p->pid != p->ppid) { -+ if (kill(p->pid, signo) != 0) { -+ bb_perror_msg( "Could not kill pid '%d'", p->pid); -+ errors++; -+ } -+ } -+ } -+ } -+#endif - #ifdef CONFIG_KILLALL - else { - pid_t myPid=getpid(); diff --git a/obsolete-buildroot/sources/busybox-openwrt-110-telnetd.patch b/obsolete-buildroot/sources/busybox-openwrt-110-telnetd.patch deleted file mode 100644 index e95757ee4e..0000000000 --- a/obsolete-buildroot/sources/busybox-openwrt-110-telnetd.patch +++ /dev/null @@ -1,53 +0,0 @@ -diff -urN busybox-1.00-pre8/networking/telnetd.c busybox-1.00-pre8-openwrt/networking/telnetd.c ---- busybox-1.00-pre8/networking/telnetd.c 2004-02-22 03:45:57.000000000 -0600 -+++ busybox-1.00-pre8-openwrt/networking/telnetd.c 2004-03-05 01:32:57.000000000 -0600 -@@ -44,6 +44,8 @@ - #include - #include - #include -+#include -+ - - #include "busybox.h" - -@@ -384,11 +386,13 @@ - int portnbr = 23; - #endif /* CONFIG_FEATURE_TELNETD_INETD */ - int c; -+ char *interface_name = NULL; -+ struct ifreq interface; - static const char options[] = - #ifdef CONFIG_FEATURE_TELNETD_INETD -- "f:l:"; --#else /* CONFIG_EATURE_TELNETD_INETD */ -- "f:l:p:"; -+ "i:f:l:"; -+#else /* CONFIG_FEATURE_TELNETD_INETD */ -+ "i:f:l:p:"; - #endif /* CONFIG_FEATURE_TELNETD_INETD */ - int maxlen, w, r; - -@@ -403,6 +407,9 @@ - case 'f': - issuefile = strdup (optarg); - break; -+ case 'i': -+ interface_name = strdup(optarg); -+ break; - case 'l': - loginpath = strdup (optarg); - break; -@@ -442,6 +449,13 @@ - sa.sin_family = AF_INET; - sa.sin_port = htons(portnbr); - -+ /* Set it to listen on the specified interface */ -+ if (interface_name) { -+ strncpy(interface.ifr_ifrn.ifrn_name, interface_name, IFNAMSIZ); -+ (void)setsockopt(master_fd, SOL_SOCKET, -+ SO_BINDTODEVICE, &interface, sizeof(interface)); -+ } -+ - if (bind(master_fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { - bb_perror_msg_and_die("bind"); - } diff --git a/obsolete-buildroot/sources/busybox-openwrt-120-udhcp.patch b/obsolete-buildroot/sources/busybox-openwrt-120-udhcp.patch deleted file mode 100644 index f8e8d33b3a..0000000000 --- a/obsolete-buildroot/sources/busybox-openwrt-120-udhcp.patch +++ /dev/null @@ -1,129 +0,0 @@ -diff -urN busybox-dist/networking/udhcp/dumpleases.c busybox/networking/udhcp/dumpleases.c ---- busybox-dist/networking/udhcp/dumpleases.c 2004-03-15 02:29:00.000000000 -0600 -+++ busybox/networking/udhcp/dumpleases.c 2004-03-16 09:52:32.000000000 -0600 -@@ -42,7 +42,7 @@ - #endif - { - FILE *fp; -- int i, c, mode = REMAINING; -+ int i, c, mode = ABSOLUTE; - long expires; - const char *file = LEASES_FILE; - struct dhcpOfferedAddr lease; -@@ -73,7 +73,7 @@ - - fp = xfopen(file, "r"); - -- printf("Mac Address IP-Address Expires %s\n", mode == REMAINING ? "in" : "at"); -+ printf("Mac Address IP-Address Hostname Expires %s\n", mode == REMAINING ? "in" : "at"); - /* "00:00:00:00:00:00 255.255.255.255 Wed Jun 30 21:49:08 1993" */ - while (fread(&lease, sizeof(lease), 1, fp)) { - -@@ -84,7 +84,8 @@ - addr.s_addr = lease.yiaddr; - printf(" %-15s", inet_ntoa(addr)); - expires = ntohl(lease.expires); -- printf(" "); -+ //expires = lease.expires; -+ printf(" %-15s ",lease.hostname); - if (mode == REMAINING) { - if (!expires) printf("expired\n"); - else { -diff -urN busybox-dist/networking/udhcp/files.c busybox/networking/udhcp/files.c ---- busybox-dist/networking/udhcp/files.c 2004-03-15 02:29:00.000000000 -0600 -+++ busybox/networking/udhcp/files.c 2004-03-16 09:50:04.000000000 -0600 -@@ -281,7 +281,7 @@ - if (lease.yiaddr >= server_config.start && lease.yiaddr <= server_config.end) { - lease.expires = ntohl(lease.expires); - if (!server_config.remaining) lease.expires -= time(0); -- if (!(add_lease(lease.chaddr, lease.yiaddr, lease.expires))) { -+ if (!(add_lease(lease.hostname, lease.chaddr, lease.yiaddr, lease.expires))) { - LOG(LOG_WARNING, "Too many leases while loading %s\n", file); - break; - } -diff -urN busybox-dist/networking/udhcp/leases.c busybox/networking/udhcp/leases.c ---- busybox-dist/networking/udhcp/leases.c 2004-03-15 02:29:00.000000000 -0600 -+++ busybox/networking/udhcp/leases.c 2004-03-16 09:50:04.000000000 -0600 -@@ -35,7 +35,7 @@ - - - /* add a lease into the table, clearing out any old ones */ --struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) -+struct dhcpOfferedAddr *add_lease(uint8_t *hostname, uint8_t *chaddr, uint32_t yiaddr, unsigned long lease) - { - struct dhcpOfferedAddr *oldest; - -@@ -45,6 +45,13 @@ - oldest = oldest_expired_lease(); - - if (oldest) { -+ if (hostname) { -+ uint8_t length = *(hostname-1); -+ if (length>15) length=15; -+ memcpy(oldest->hostname,hostname,length); -+ oldest->hostname[length]=0; -+ } -+ - memcpy(oldest->chaddr, chaddr, 16); - oldest->yiaddr = yiaddr; - oldest->expires = time(0) + lease; -@@ -112,7 +119,7 @@ - temp.s_addr = addr; - LOG(LOG_INFO, "%s belongs to someone, reserving it for %ld seconds", - inet_ntoa(temp), server_config.conflict_time); -- add_lease(blank_chaddr, addr, server_config.conflict_time); -+ add_lease(blank_chaddr, blank_chaddr, addr, server_config.conflict_time); - return 1; - } else return 0; - } -diff -urN busybox-dist/networking/udhcp/leases.h busybox/networking/udhcp/leases.h ---- busybox-dist/networking/udhcp/leases.h 2004-01-30 17:45:12.000000000 -0600 -+++ busybox/networking/udhcp/leases.h 2004-03-16 09:50:04.000000000 -0600 -@@ -4,6 +4,7 @@ - - - struct dhcpOfferedAddr { -+ uint8_t hostname[16]; - uint8_t chaddr[16]; - uint32_t yiaddr; /* network order */ - uint32_t expires; /* host order */ -@@ -12,7 +13,7 @@ - extern uint8_t blank_chaddr[]; - - void clear_lease(uint8_t *chaddr, uint32_t yiaddr); --struct dhcpOfferedAddr *add_lease(uint8_t *chaddr, uint32_t yiaddr, unsigned long lease); -+struct dhcpOfferedAddr *add_lease(uint8_t *hostname, uint8_t *chaddr, uint32_t yiaddr, unsigned long lease); - int lease_expired(struct dhcpOfferedAddr *lease); - struct dhcpOfferedAddr *oldest_expired_lease(void); - struct dhcpOfferedAddr *find_lease_by_chaddr(uint8_t *chaddr); -diff -urN busybox-dist/networking/udhcp/serverpacket.c busybox/networking/udhcp/serverpacket.c ---- busybox-dist/networking/udhcp/serverpacket.c 2004-03-15 02:29:01.000000000 -0600 -+++ busybox/networking/udhcp/serverpacket.c 2004-03-16 09:51:36.000000000 -0600 -@@ -29,6 +29,7 @@ - #include "dhcpd.h" - #include "options.h" - #include "common.h" -+#include "files.h" - - /* send a packet to giaddr using the kernel ip stack */ - static int send_packet_to_relay(struct dhcpMessage *payload) -@@ -152,7 +153,7 @@ - return -1; - } - -- if (!add_lease(packet.chaddr, packet.yiaddr, server_config.offer_time)) { -+ if (!add_lease(get_option(oldpacket, DHCP_HOST_NAME), packet.chaddr, packet.yiaddr, server_config.offer_time)) { - LOG(LOG_WARNING, "lease pool is full -- OFFER abandoned"); - return -1; - } -@@ -233,7 +234,9 @@ - if (send_packet(&packet, 0) < 0) - return -1; - -- add_lease(packet.chaddr, packet.yiaddr, lease_time_align); -+ add_lease(get_option(oldpacket, DHCP_HOST_NAME), packet.chaddr, packet.yiaddr, lease_time_align); -+ -+ write_leases(); - - return 0; - } diff --git a/obsolete-buildroot/sources/busybox-openwrt-130-resetmon.patch b/obsolete-buildroot/sources/busybox-openwrt-130-resetmon.patch deleted file mode 100644 index b41315e1f7..0000000000 --- a/obsolete-buildroot/sources/busybox-openwrt-130-resetmon.patch +++ /dev/null @@ -1,89 +0,0 @@ -diff -urN busybox-dist/include/applets.h busybox/include/applets.h ---- busybox-dist/include/applets.h 2004-03-16 09:56:27.000000000 -0600 -+++ busybox/include/applets.h 2004-03-16 10:00:14.000000000 -0600 -@@ -484,6 +484,9 @@ - #ifdef CONFIG_RESET - APPLET(reset, reset_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) - #endif -+#ifdef CONFIG_RESETMON -+ APPLET(resetmon, resetmon_main, _BB_DIR_SBIN, _BB_SUID_NEVER) -+#endif - #ifdef CONFIG_RM - APPLET(rm, rm_main, _BB_DIR_BIN, _BB_SUID_NEVER) - #endif -diff -urN busybox-dist/include/usage.h busybox/include/usage.h ---- busybox-dist/include/usage.h 2004-03-16 09:56:27.000000000 -0600 -+++ busybox/include/usage.h 2004-03-16 10:00:14.000000000 -0600 -@@ -2024,6 +2024,11 @@ - #define reset_full_usage \ - "Resets the screen." - -+#define resetmon_trivial_usage \ -+ "" -+#define resetmon_full_usage \ -+ "Return an exit code of TRUE (0) if reset is NOT pressed." -+ - #define rm_trivial_usage \ - "[OPTION]... FILE..." - #define rm_full_usage \ -diff -urN busybox-dist/miscutils/Config.in busybox/miscutils/Config.in ---- busybox-dist/miscutils/Config.in 2004-03-15 02:28:46.000000000 -0600 -+++ busybox/miscutils/Config.in 2004-03-16 10:00:14.000000000 -0600 -@@ -156,6 +156,12 @@ - to advance or rewind a tape past a specified number of archive - files on the tape. - -+config CONFIG_RESETMON -+ bool "resetmon" -+ default y -+ help -+ Linksys wrt54g reset button monitor. Returns TRUE if NOT pressed. -+ - config CONFIG_RX - bool "rx" - default n -diff -urN busybox-dist/miscutils/Makefile.in busybox/miscutils/Makefile.in ---- busybox-dist/miscutils/Makefile.in 2004-03-15 02:28:46.000000000 -0600 -+++ busybox/miscutils/Makefile.in 2004-03-16 10:00:14.000000000 -0600 -@@ -33,6 +33,7 @@ - MISCUTILS-$(CONFIG_LAST) += last.o - MISCUTILS-$(CONFIG_MAKEDEVS) += makedevs.o - MISCUTILS-$(CONFIG_MT) += mt.o -+MISCUTILS-$(CONFIG_RESETMON) += resetmon.o - MISCUTILS-$(CONFIG_RX) += rx.o - MISCUTILS-$(CONFIG_STRINGS) += strings.o - MISCUTILS-$(CONFIG_TIME) += time.o -diff -urN busybox-dist/miscutils/resetmon.c busybox/miscutils/resetmon.c ---- busybox-dist/miscutils/resetmon.c 1969-12-31 18:00:00.000000000 -0600 -+++ busybox/miscutils/resetmon.c 2004-03-16 10:00:14.000000000 -0600 -@@ -0,0 +1,30 @@ -+#include -+#include -+#include "busybox.h" -+ -+#define RESET (1<<6) -+ -+int resetmon_main(int argc, char **argv) { -+ int fd = -1; -+ unsigned int val=0; -+ -+#if 0 -+ if ((fd = open("/dev/gpio/control",O_RDWR))<0) goto error; -+ read(fd,&val,4); -+ val|=RESET; -+ write(fd,&val,4); -+ -+ if ((fd = open("/dev/gpio/outen",O_RDWR))<0) goto error; -+ read(fd,&val,4); -+ val&=~RESET; -+ write(fd,&val,4); -+#endif -+ -+ if ((fd = open("/dev/gpio/in",O_RDONLY))<0) goto error; -+ read(fd,&val,4); -+ -+ return !(val&RESET); -+ -+error: -+ return 1; -+} diff --git a/obsolete-buildroot/sources/busybox.config b/obsolete-buildroot/sources/busybox.config deleted file mode 100644 index 2d7c51fb34..0000000000 --- a/obsolete-buildroot/sources/busybox.config +++ /dev/null @@ -1,459 +0,0 @@ -# -# Automatically generated make config: don't edit -# -HAVE_DOT_CONFIG=y - -# -# General Configuration -# -# CONFIG_FEATURE_BUFFERS_USE_MALLOC is not set -CONFIG_FEATURE_BUFFERS_GO_ON_STACK=y -# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set -CONFIG_FEATURE_VERBOSE_USAGE=y -# CONFIG_FEATURE_INSTALLER is not set -# CONFIG_LOCALE_SUPPORT is not set -CONFIG_FEATURE_DEVFS=y -CONFIG_FEATURE_DEVPTS=y -# CONFIG_FEATURE_CLEAN_UP is not set -# CONFIG_FEATURE_SUID is not set -# CONFIG_SELINUX is not set - -# -# Build Options -# -# CONFIG_STATIC is not set -CONFIG_LFS=y -USING_CROSS_COMPILER=y -CROSS_COMPILER_PREFIX="mipsel-uclibc-" -EXTRA_CFLAGS_OPTIONS="-Os " - -# -# Installation Options -# -# CONFIG_INSTALL_NO_USR is not set -PREFIX="./_install" - -# -# Archival Utilities -# -# CONFIG_AR is not set -CONFIG_BUNZIP2=y -# CONFIG_CPIO is not set -# CONFIG_DPKG is not set -# CONFIG_DPKG_DEB is not set -CONFIG_GUNZIP=y -CONFIG_FEATURE_GUNZIP_UNCOMPRESS=y -CONFIG_GZIP=y -# CONFIG_RPM2CPIO is not set -# CONFIG_RPM is not set -CONFIG_TAR=y -CONFIG_FEATURE_TAR_CREATE=y -CONFIG_FEATURE_TAR_BZIP2=y -# CONFIG_FEATURE_TAR_FROM is not set -CONFIG_FEATURE_TAR_GZIP=y -# CONFIG_FEATURE_TAR_COMPRESS is not set -# CONFIG_FEATURE_TAR_OLDGNU_COMPATABILITY is not set -CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y -# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set -# CONFIG_UNCOMPRESS is not set -# CONFIG_UNZIP is not set - -# -# Common options for cpio and tar -# -# CONFIG_FEATURE_UNARCHIVE_TAPE is not set - -# -# Coreutils -# -CONFIG_BASENAME=y -# CONFIG_CAL is not set -CONFIG_CAT=y -CONFIG_CHGRP=y -CONFIG_CHMOD=y -CONFIG_CHOWN=y -CONFIG_CHROOT=y -# CONFIG_CMP is not set -CONFIG_CP=y -CONFIG_CUT=y -CONFIG_DATE=y -CONFIG_FEATURE_DATE_ISOFMT=y -CONFIG_DD=y -CONFIG_DF=y -# CONFIG_DIRNAME is not set -# CONFIG_DOS2UNIX is not set -# CONFIG_DU is not set -CONFIG_ECHO=y -CONFIG_FEATURE_FANCY_ECHO=y -CONFIG_ENV=y -CONFIG_EXPR=y -CONFIG_FALSE=y -# CONFIG_FOLD is not set -CONFIG_HEAD=y -# CONFIG_FEATURE_FANCY_HEAD is not set -CONFIG_HOSTID=y -# CONFIG_ID is not set -CONFIG_INSTALL=y -CONFIG_LENGTH=y -CONFIG_LN=y -# CONFIG_LOGNAME is not set -CONFIG_LS=y -CONFIG_FEATURE_LS_FILETYPES=y -CONFIG_FEATURE_LS_FOLLOWLINKS=y -CONFIG_FEATURE_LS_RECURSIVE=y -CONFIG_FEATURE_LS_SORTFILES=y -CONFIG_FEATURE_LS_TIMESTAMPS=y -CONFIG_FEATURE_LS_USERNAME=y -CONFIG_FEATURE_LS_COLOR=y -CONFIG_MD5SUM=y -CONFIG_MKDIR=y -CONFIG_MKFIFO=y -# CONFIG_MKNOD is not set -CONFIG_MV=y -# CONFIG_OD is not set -# CONFIG_PRINTF is not set -CONFIG_PWD=y -# CONFIG_REALPATH is not set -CONFIG_RM=y -CONFIG_RMDIR=y -# CONFIG_SEQ is not set -# CONFIG_SHA1SUM is not set -CONFIG_SLEEP=y -CONFIG_FEATURE_FANCY_SLEEP=y -CONFIG_SORT=y -# CONFIG_STTY is not set -CONFIG_SYNC=y -CONFIG_TAIL=y -CONFIG_FEATURE_FANCY_TAIL=y -CONFIG_TEE=y -CONFIG_FEATURE_TEE_USE_BLOCK_IO=y -CONFIG_TEST=y - -# -# test (forced enabled for use with shell) -# -CONFIG_TOUCH=y -# CONFIG_TR is not set -CONFIG_TRUE=y -# CONFIG_TTY is not set -CONFIG_UNAME=y -CONFIG_UNIQ=y -# CONFIG_USLEEP is not set -# CONFIG_UUDECODE is not set -# CONFIG_UUENCODE is not set -# CONFIG_WATCH is not set -CONFIG_WC=y -# CONFIG_WHO is not set -# CONFIG_WHOAMI is not set -CONFIG_YES=y - -# -# Common options for cp and mv -# -CONFIG_FEATURE_PRESERVE_HARDLINKS=y - -# -# Common options for ls and more -# -CONFIG_FEATURE_AUTOWIDTH=y - -# -# Common options for df, du, ls -# -CONFIG_FEATURE_HUMAN_READABLE=y - -# -# Common options for md5sum, sha1sum -# -CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y - -# -# Console Utilities -# -# CONFIG_CHVT is not set -CONFIG_CLEAR=y -# CONFIG_DEALLOCVT is not set -# CONFIG_DUMPKMAP is not set -# CONFIG_LOADFONT is not set -# CONFIG_LOADKMAP is not set -# CONFIG_OPENVT is not set -CONFIG_RESET=y -# CONFIG_SETKEYCODES is not set - -# -# Debian Utilities -# -CONFIG_MKTEMP=y -# CONFIG_PIPE_PROGRESS is not set -# CONFIG_READLINK is not set -CONFIG_RUN_PARTS=y -# CONFIG_START_STOP_DAEMON is not set -CONFIG_WHICH=y - -# -# Editors -# -CONFIG_AWK=y -CONFIG_FEATURE_AWK_MATH=y -# CONFIG_PATCH is not set -CONFIG_SED=y -CONFIG_VI=y -CONFIG_FEATURE_VI_COLON=y -CONFIG_FEATURE_VI_YANKMARK=y -CONFIG_FEATURE_VI_SEARCH=y -CONFIG_FEATURE_VI_USE_SIGNALS=y -CONFIG_FEATURE_VI_DOT_CMD=y -CONFIG_FEATURE_VI_READONLY=y -CONFIG_FEATURE_VI_SETOPTS=y -CONFIG_FEATURE_VI_SET=y -CONFIG_FEATURE_VI_WIN_RESIZE=y -CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y - -# -# Finding Utilities -# -CONFIG_FIND=y -# CONFIG_FEATURE_FIND_MTIME is not set -CONFIG_FEATURE_FIND_PERM=y -CONFIG_FEATURE_FIND_TYPE=y -CONFIG_FEATURE_FIND_XDEV=y -# CONFIG_FEATURE_FIND_NEWER is not set -# CONFIG_FEATURE_FIND_INUM is not set -CONFIG_GREP=y -CONFIG_FEATURE_GREP_EGREP_ALIAS=y -CONFIG_FEATURE_GREP_FGREP_ALIAS=y -CONFIG_FEATURE_GREP_CONTEXT=y -CONFIG_XARGS=y -CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y -CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y -CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y -CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y - -# -# Init Utilities -# -CONFIG_INIT=y -CONFIG_FEATURE_USE_INITTAB=y -# CONFIG_FEATURE_INITRD is not set -# CONFIG_FEATURE_INIT_COREDUMPS is not set -# CONFIG_FEATURE_EXTRA_QUIET is not set -# CONFIG_HALT is not set -# CONFIG_POWEROFF is not set -CONFIG_REBOOT=y -CONFIG_MESG=y - -# -# Login/Password Management Utilities -# -# CONFIG_USE_BB_PWD_GRP is not set -# CONFIG_ADDGROUP is not set -# CONFIG_DELGROUP is not set -# CONFIG_ADDUSER is not set -# CONFIG_DELUSER is not set -# CONFIG_GETTY is not set -# CONFIG_LOGIN is not set -CONFIG_PASSWD=y -# CONFIG_SU is not set -# CONFIG_SULOGIN is not set -# CONFIG_VLOCK is not set - -# -# Miscellaneous Utilities -# -# CONFIG_ADJTIMEX is not set -CONFIG_CROND=y -# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set -CONFIG_CRONTAB=y -# CONFIG_DC is not set -# CONFIG_DEVFSD is not set -# CONFIG_LAST is not set -# CONFIG_HDPARM is not set -# CONFIG_MAKEDEVS is not set -# CONFIG_MT is not set -CONFIG_RESETMON=y -# CONFIG_RX is not set -CONFIG_STRINGS=y -CONFIG_TIME=y -# CONFIG_WATCHDOG is not set - -# -# Linux Module Utilities -# -CONFIG_INSMOD=y -CONFIG_FEATURE_2_4_MODULES=y -# CONFIG_FEATURE_2_6_MODULES is not set -# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set -# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set -# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set -# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set -CONFIG_LSMOD=y -CONFIG_FEATURE_QUERY_MODULE_INTERFACE=y -# CONFIG_MODPROBE is not set -CONFIG_RMMOD=y -# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set - -# -# Networking Utilities -# -CONFIG_FEATURE_IPV6=y -CONFIG_ARPING=y -# CONFIG_FTPGET is not set -# CONFIG_FTPPUT is not set -# CONFIG_HOSTNAME is not set -CONFIG_HTTPD=y -# CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY is not set -CONFIG_FEATURE_HTTPD_BASIC_AUTH=y -CONFIG_FEATURE_HTTPD_AUTH_MD5=y -CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP=y -# CONFIG_FEATURE_HTTPD_SETUID is not set -CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES=y -CONFIG_FEATURE_HTTPD_CGI=y -CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y -CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y -CONFIG_IFCONFIG=y -CONFIG_FEATURE_IFCONFIG_STATUS=y -# CONFIG_FEATURE_IFCONFIG_SLIP is not set -# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set -CONFIG_FEATURE_IFCONFIG_HW=y -CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y -# CONFIG_IFUPDOWN is not set -# CONFIG_INETD is not set -# CONFIG_IP is not set -CONFIG_IPCALC=y -CONFIG_FEATURE_IPCALC_FANCY=y -# CONFIG_IPADDR is not set -# CONFIG_IPLINK is not set -# CONFIG_IPROUTE is not set -# CONFIG_IPTUNNEL is not set -# CONFIG_NAMEIF is not set -CONFIG_NC=y -CONFIG_NETSTAT=y -CONFIG_NSLOOKUP=y -CONFIG_PING=y -CONFIG_FEATURE_FANCY_PING=y -CONFIG_PING6=y -CONFIG_FEATURE_FANCY_PING6=y -CONFIG_ROUTE=y -# CONFIG_TELNET is not set -CONFIG_TELNETD=y -# CONFIG_FEATURE_TELNETD_INETD is not set -# CONFIG_TFTP is not set -CONFIG_TRACEROUTE=y -CONFIG_FEATURE_TRACEROUTE_VERBOSE=y -CONFIG_VCONFIG=y -CONFIG_WGET=y -CONFIG_FEATURE_WGET_STATUSBAR=y -CONFIG_FEATURE_WGET_AUTHENTICATION=y -CONFIG_FEATURE_WGET_IP6_LITERAL=y - -# -# udhcp Server/Client -# -# CONFIG_UDHCPD is not set -CONFIG_UDHCPC=y -# CONFIG_FEATURE_UDHCP_SYSLOG is not set -# CONFIG_FEATURE_UDHCP_DEBUG is not set - -# -# Process Utilities -# -CONFIG_FREE=y -CONFIG_KILL=y -CONFIG_KILLALL=y -CONFIG_KILLALL5=y -CONFIG_PIDOF=y -CONFIG_PS=y -# CONFIG_RENICE is not set -CONFIG_TOP=y -FEATURE_CPU_USAGE_PERCENTAGE=y -CONFIG_UPTIME=y -CONFIG_SYSCTL=y - -# -# Another Bourne-like Shell -# -CONFIG_FEATURE_SH_IS_ASH=y -# CONFIG_FEATURE_SH_IS_HUSH is not set -# CONFIG_FEATURE_SH_IS_LASH is not set -# CONFIG_FEATURE_SH_IS_MSH is not set -# CONFIG_FEATURE_SH_IS_NONE is not set -CONFIG_ASH=y - -# -# Ash Shell Options -# -CONFIG_ASH_JOB_CONTROL=y -CONFIG_ASH_ALIAS=y -CONFIG_ASH_MATH_SUPPORT=y -# CONFIG_ASH_MATH_SUPPORT_64 is not set -CONFIG_ASH_GETOPTS=y -CONFIG_ASH_CMDCMD=y -# CONFIG_ASH_MAIL is not set -CONFIG_ASH_OPTIMIZE_FOR_SIZE=y -# CONFIG_ASH_RANDOM_SUPPORT is not set -# CONFIG_HUSH is not set -# CONFIG_LASH is not set -# CONFIG_MSH is not set - -# -# Bourne Shell Options -# -# CONFIG_FEATURE_SH_EXTRA_QUIET is not set -# CONFIG_FEATURE_SH_STANDALONE_SHELL is not set -CONFIG_FEATURE_COMMAND_EDITING=y -CONFIG_FEATURE_COMMAND_HISTORY=15 -# CONFIG_FEATURE_COMMAND_SAVEHISTORY is not set -CONFIG_FEATURE_COMMAND_TAB_COMPLETION=y -# CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION is not set -CONFIG_FEATURE_SH_FANCY_PROMPT=y - -# -# System Logging Utilities -# -CONFIG_SYSLOGD=y -CONFIG_FEATURE_ROTATE_LOGFILE=y -CONFIG_FEATURE_REMOTE_LOG=y -CONFIG_FEATURE_IPC_SYSLOG=y -CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16 -CONFIG_LOGREAD=y -# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set -CONFIG_KLOGD=y -CONFIG_LOGGER=y - -# -# Linux System Utilities -# -CONFIG_DMESG=y -# CONFIG_FBSET is not set -# CONFIG_FDFLUSH is not set -# CONFIG_FDFORMAT is not set -# CONFIG_FDISK is not set -FDISK_SUPPORT_LARGE_DISKS=y -# CONFIG_FREERAMDISK is not set -# CONFIG_FSCK_MINIX is not set -# CONFIG_MKFS_MINIX is not set -# CONFIG_GETOPT is not set -CONFIG_HEXDUMP=y -# CONFIG_HWCLOCK is not set -# CONFIG_LOSETUP is not set -# CONFIG_MKSWAP is not set -CONFIG_MORE=y -CONFIG_FEATURE_USE_TERMIOS=y -CONFIG_PIVOT_ROOT=y -CONFIG_RDATE=y -# CONFIG_SWAPONOFF is not set -CONFIG_MOUNT=y -CONFIG_NFSMOUNT=y -CONFIG_UMOUNT=y -CONFIG_FEATURE_MOUNT_FORCE=y - -# -# Common options for mount/umount -# -CONFIG_FEATURE_MOUNT_LOOP=y -# CONFIG_FEATURE_MTAB_SUPPORT is not set - -# -# Debugging Options -# -# CONFIG_DEBUG is not set diff --git a/obsolete-buildroot/sources/compressed-20040531.tar.bz2 b/obsolete-buildroot/sources/compressed-20040531.tar.bz2 deleted file mode 100644 index c8e06b8a9b..0000000000 Binary files a/obsolete-buildroot/sources/compressed-20040531.tar.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/cramfs.patch b/obsolete-buildroot/sources/cramfs.patch deleted file mode 100644 index 884eb8cb83..0000000000 --- a/obsolete-buildroot/sources/cramfs.patch +++ /dev/null @@ -1,1269 +0,0 @@ ---- cramfs-1.1.orig/cramfsck.c 2002-02-22 17:00:42.000000000 -0700 -+++ cramfs-1.1/cramfsck.c 2002-12-21 01:25:17.000000000 -0700 -@@ -51,10 +51,11 @@ - #include - #include - #define _LINUX_STRING_H_ --#include --#include -+#include "linux/cramfs_fs.h" - #include - -+#define BLKGETSIZE _IO(0x12,96) /* return device size /512 (long *arg) */ -+ - /* Exit codes used by fsck-type programs */ - #define FSCK_OK 0 /* No errors */ - #define FSCK_NONDESTRUCT 1 /* File system errors corrected */ -@@ -75,7 +76,7 @@ - static int opt_verbose = 0; /* 1 = verbose (-v), 2+ = very verbose (-vv) */ - #ifdef INCLUDE_FS_TESTS - static int opt_extract = 0; /* extract cramfs (-x) */ --static char *extract_dir = "root"; /* extraction directory (-x) */ -+static char *extract_dir = "/"; /* extraction directory (-x) */ - static uid_t euid; /* effective UID */ - - /* (cramfs_super + start) <= start_dir < end_dir <= start_data <= end_data */ -@@ -155,7 +156,7 @@ - } - - if (*length < sizeof(struct cramfs_super)) { -- die(FSCK_UNCORRECTED, 0, "file length too short"); -+ die(FSCK_UNCORRECTED, 0, "filesystem smaller than a cramfs superblock!"); - } - - /* find superblock */ -@@ -190,7 +191,8 @@ - die(FSCK_UNCORRECTED, 0, "zero file count"); - } - if (*length < super.size) { -- die(FSCK_UNCORRECTED, 0, "file length too short"); -+ die(FSCK_UNCORRECTED, 0, "file length too short, %lu is smaller than %lu", -+ *length, super.size); - } - else if (*length > super.size) { - fprintf(stderr, "warning: file extends past end of filesystem\n"); -@@ -267,11 +269,11 @@ - #ifdef INCLUDE_FS_TESTS - static void print_node(char type, struct cramfs_inode *i, char *name) - { -- char info[10]; -+ char info[11]; - - if (S_ISCHR(i->mode) || (S_ISBLK(i->mode))) { - /* major/minor numbers can be as high as 2^12 or 4096 */ -- snprintf(info, 10, "%4d,%4d", major(i->size), minor(i->size)); -+ snprintf(info, 11, "%4d,%4d", major(i->size), minor(i->size)); - } - else { - /* size be as high as 2^24 or 16777216 */ -@@ -445,8 +447,10 @@ - } - /* TODO: Do we need to check end_dir for empty case? */ - memcpy(newpath, path, pathlen); -- newpath[pathlen] = '/'; -- pathlen++; -+ if (pathlen > 1) { -+ newpath[pathlen] = '/'; -+ pathlen++; -+ } - if (opt_verbose) { - print_node('d', i, path); - } ---- cramfs-1.1.orig/device_table.txt 1969-12-31 17:00:00.000000000 -0700 -+++ cramfs-1.1/device_table.txt 2003-01-01 05:13:44.000000000 -0700 -@@ -0,0 +1,129 @@ -+# When building a target filesystem, it is desirable to not have to -+# become root and then run 'mknod' a thousand times. Using a device -+# table you can create device nodes and directories "on the fly". -+# -+# This is a sample device table file for use with mkcramfs. You can -+# do all sorts of interesting things with a device table file. For -+# example, if you want to adjust the permissions on a particular file -+# you can just add an entry like: -+# /sbin/foobar f 2755 0 0 - - - - - -+# and (assuming the file /sbin/foobar exists) it will be made setuid -+# root (regardless of what its permissions are on the host filesystem. -+# Furthermore, you can use a single table entry to create a many device -+# minors. For example, if I wanted to create /dev/hda and /dev/hda[0-15] -+# I could just use the following two table entries: -+# /dev/hda b 640 0 0 3 0 0 0 - -+# /dev/hda b 640 0 0 3 1 1 1 15 -+# -+# Device table entries take the form of: -+# -+# where name is the file name, type can be one of: -+# f A regular file -+# d Directory -+# c Character special device file -+# b Block special device file -+# p Fifo (named pipe) -+# uid is the user id for the target file, gid is the group id for the -+# target file. The rest of the entries (major, minor, etc) apply only -+# to device special files. -+ -+# Have fun -+# -Erik Andersen -+# -+ -+# -+/dev d 755 0 0 - - - - - -+/dev/mem c 640 0 0 1 1 0 0 - -+/dev/kmem c 640 0 0 1 2 0 0 - -+/dev/null c 640 0 0 1 3 0 0 - -+/dev/zero c 640 0 0 1 5 0 0 - -+/dev/random c 640 0 0 1 8 0 0 - -+/dev/urandom c 640 0 0 1 9 0 0 - -+/dev/tty c 666 0 0 5 0 0 0 - -+/dev/tty c 666 0 0 4 0 0 1 6 -+/dev/console c 640 0 0 5 1 0 0 - -+/dev/ram b 640 0 0 1 1 0 0 - -+/dev/ram b 640 0 0 1 0 0 1 4 -+/dev/loop b 640 0 0 7 0 0 1 2 -+/dev/ptmx c 666 0 0 5 2 0 0 - -+#/dev/ttyS c 640 0 0 4 64 0 1 4 -+#/dev/psaux c 640 0 0 10 1 0 0 - -+#/dev/rtc c 640 0 0 10 135 0 0 - -+ -+# Adjust permissions on some normal files -+#/etc/shadow f 600 0 0 - - - - - -+#/bin/tinylogin f 4755 0 0 - - - - - -+ -+# User-mode Linux stuff -+/dev/ubda b 640 0 0 98 0 0 0 - -+/dev/ubda b 640 0 0 98 1 1 1 15 -+ -+# IDE Devices -+/dev/hda b 640 0 0 3 0 0 0 - -+/dev/hda b 640 0 0 3 1 1 1 15 -+/dev/hdb b 640 0 0 3 64 0 0 - -+/dev/hdb b 640 0 0 3 65 1 1 15 -+#/dev/hdc b 640 0 0 22 0 0 0 - -+#/dev/hdc b 640 0 0 22 1 1 1 15 -+#/dev/hdd b 640 0 0 22 64 0 0 - -+#/dev/hdd b 640 0 0 22 65 1 1 15 -+#/dev/hde b 640 0 0 33 0 0 0 - -+#/dev/hde b 640 0 0 33 1 1 1 15 -+#/dev/hdf b 640 0 0 33 64 0 0 - -+#/dev/hdf b 640 0 0 33 65 1 1 15 -+#/dev/hdg b 640 0 0 34 0 0 0 - -+#/dev/hdg b 640 0 0 34 1 1 1 15 -+#/dev/hdh b 640 0 0 34 64 0 0 - -+#/dev/hdh b 640 0 0 34 65 1 1 15 -+ -+# SCSI Devices -+#/dev/sda b 640 0 0 8 0 0 0 - -+#/dev/sda b 640 0 0 8 1 1 1 15 -+#/dev/sdb b 640 0 0 8 16 0 0 - -+#/dev/sdb b 640 0 0 8 17 1 1 15 -+#/dev/sdc b 640 0 0 8 32 0 0 - -+#/dev/sdc b 640 0 0 8 33 1 1 15 -+#/dev/sdd b 640 0 0 8 48 0 0 - -+#/dev/sdd b 640 0 0 8 49 1 1 15 -+#/dev/sde b 640 0 0 8 64 0 0 - -+#/dev/sde b 640 0 0 8 65 1 1 15 -+#/dev/sdf b 640 0 0 8 80 0 0 - -+#/dev/sdf b 640 0 0 8 81 1 1 15 -+#/dev/sdg b 640 0 0 8 96 0 0 - -+#/dev/sdg b 640 0 0 8 97 1 1 15 -+#/dev/sdh b 640 0 0 8 112 0 0 - -+#/dev/sdh b 640 0 0 8 113 1 1 15 -+#/dev/sg c 640 0 0 21 0 0 1 15 -+#/dev/scd b 640 0 0 11 0 0 1 15 -+#/dev/st c 640 0 0 9 0 0 1 8 -+#/dev/nst c 640 0 0 9 128 0 1 8 -+#/dev/st c 640 0 0 9 32 1 1 4 -+#/dev/st c 640 0 0 9 64 1 1 4 -+#/dev/st c 640 0 0 9 96 1 1 4 -+ -+# Floppy disk devices -+#/dev/fd b 640 0 0 2 0 0 1 2 -+#/dev/fd0d360 b 640 0 0 2 4 0 0 - -+#/dev/fd1d360 b 640 0 0 2 5 0 0 - -+#/dev/fd0h1200 b 640 0 0 2 8 0 0 - -+#/dev/fd1h1200 b 640 0 0 2 9 0 0 - -+#/dev/fd0u1440 b 640 0 0 2 28 0 0 - -+#/dev/fd1u1440 b 640 0 0 2 29 0 0 - -+#/dev/fd0u2880 b 640 0 0 2 32 0 0 - -+#/dev/fd1u2880 b 640 0 0 2 33 0 0 - -+ -+# All the proprietary cdrom devices in the world -+#/dev/aztcd b 640 0 0 29 0 0 0 - -+#/dev/bpcd b 640 0 0 41 0 0 0 - -+#/dev/capi20 c 640 0 0 68 0 0 1 2 -+#/dev/cdu31a b 640 0 0 15 0 0 0 - -+#/dev/cdu535 b 640 0 0 24 0 0 0 - -+#/dev/cm206cd b 640 0 0 32 0 0 0 - -+#/dev/sjcd b 640 0 0 18 0 0 0 - -+#/dev/sonycd b 640 0 0 15 0 0 0 - -+#/dev/gscd b 640 0 0 16 0 0 0 - -+#/dev/sbpcd b 640 0 0 25 0 0 0 - -+#/dev/sbpcd b 640 0 0 25 0 0 1 4 -+#/dev/mcd b 640 0 0 23 0 0 0 - -+#/dev/optcd b 640 0 0 17 0 0 0 - -+ ---- cramfs-1.1.orig/mkcramfs.c 2002-02-20 01:03:32.000000000 -0700 -+++ cramfs-1.1/mkcramfs.c 2002-12-21 01:25:17.000000000 -0700 -@@ -1,3 +1,4 @@ -+/* vi: set sw=8 ts=8: */ - /* - * mkcramfs - make a cramfs file system - * -@@ -16,12 +17,21 @@ - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ * Added device table support (code taken from mkfs.jffs2.c, credit to -+ * Erik Andersen ) as well as an option to squash -+ * permissions. - Russ Dill September 2002 -+ * -+ * Reworked, cleaned up, and updated for cramfs-1.1, December 2002 -+ * - Erik Andersen -+ * - */ - - /* - * If you change the disk format of cramfs, please update fs/cramfs/README. - */ - -+#define _GNU_SOURCE - #include - #include - #include -@@ -33,8 +43,15 @@ - #include - #include - #include -+#include -+#include -+#include -+#include - #include - #include -+#ifdef DMALLOC -+#include -+#endif - - /* Exit codes used by mkfs-type programs */ - #define MKFS_OK 0 /* No errors */ -@@ -71,11 +88,17 @@ - + (1 << CRAMFS_SIZE_WIDTH) - 1 /* filesize */ \ - + (1 << CRAMFS_SIZE_WIDTH) * 4 / PAGE_CACHE_SIZE /* block pointers */ ) - -+ -+/* The kernel assumes PAGE_CACHE_SIZE as block size. */ -+#define PAGE_CACHE_SIZE (4096) -+ -+ - static const char *progname = "mkcramfs"; - static unsigned int blksize = PAGE_CACHE_SIZE; - static long total_blocks = 0, total_nodes = 1; /* pre-count the root node */ - static int image_length = 0; - -+ - /* - * If opt_holes is set, then mkcramfs can create explicit holes in the - * data, which saves 26 bytes per hole (which is a lot smaller a -@@ -91,10 +114,12 @@ - static int opt_holes = 0; - static int opt_pad = 0; - static int opt_verbose = 0; -+static int opt_squash = 0; - static char *opt_image = NULL; - static char *opt_name = NULL; - - static int warn_dev, warn_gid, warn_namelen, warn_skip, warn_size, warn_uid; -+static const char *const memory_exhausted = "memory exhausted"; - - /* In-core version of inode / directory entry. */ - struct entry { -@@ -123,7 +148,7 @@ - { - FILE *stream = status ? stderr : stdout; - -- fprintf(stream, "usage: %s [-h] [-e edition] [-i file] [-n name] dirname outfile\n" -+ fprintf(stream, "usage: %s [-h] [-e edition] [-i file] [-n name] [-D file] dirname outfile\n" - " -h print this help\n" - " -E make all warnings errors (non-zero exit status)\n" - " -e edition set edition number (part of fsid)\n" -@@ -133,39 +158,157 @@ - " -s sort directory entries (old option, ignored)\n" - " -v be more verbose\n" - " -z make explicit holes (requires >= 2.3.39)\n" -- " dirname root of the directory tree to be compressed\n" -+ " -D Use the named FILE as a device table file\n" -+ " -q squash permissions (make everything owned by root)\n" -+ " dirname root of the filesystem to be compressed\n" - " outfile output file\n", progname, PAD_SIZE); - - exit(status); - } - --static void die(int status, int syserr, const char *fmt, ...) -+static void verror_msg(const char *s, va_list p) -+{ -+ fflush(stdout); -+ fprintf(stderr, "mkcramfs: "); -+ vfprintf(stderr, s, p); -+} -+ -+static void vperror_msg(const char *s, va_list p) -+{ -+ int err = errno; -+ -+ if (s == 0) -+ s = ""; -+ verror_msg(s, p); -+ if (*s) -+ s = ": "; -+ fprintf(stderr, "%s%s\n", s, strerror(err)); -+} -+ -+static void perror_msg(const char *s, ...) -+{ -+ va_list p; -+ -+ va_start(p, s); -+ vperror_msg(s, p); -+ va_end(p); -+} -+ -+static void error_msg_and_die(const char *s, ...) -+{ -+ va_list p; -+ -+ va_start(p, s); -+ verror_msg(s, p); -+ va_end(p); -+ putc('\n', stderr); -+ exit(MKFS_ERROR); -+} -+ -+static void perror_msg_and_die(const char *s, ...) -+{ -+ va_list p; -+ -+ va_start(p, s); -+ vperror_msg(s, p); -+ va_end(p); -+ exit(MKFS_ERROR); -+} -+#ifndef DMALLOC -+extern char *xstrdup(const char *s) -+{ -+ char *t; -+ -+ if (s == NULL) -+ return NULL; -+ t = strdup(s); -+ if (t == NULL) -+ error_msg_and_die(memory_exhausted); -+ return t; -+} -+ -+extern void *xmalloc(size_t size) -+{ -+ void *ptr = malloc(size); -+ -+ if (ptr == NULL && size != 0) -+ error_msg_and_die(memory_exhausted); -+ return ptr; -+} -+ -+extern void *xcalloc(size_t nmemb, size_t size) -+{ -+ void *ptr = calloc(nmemb, size); -+ -+ if (ptr == NULL && nmemb != 0 && size != 0) -+ error_msg_and_die(memory_exhausted); -+ return ptr; -+} -+ -+extern void *xrealloc(void *ptr, size_t size) -+{ -+ ptr = realloc(ptr, size); -+ if (ptr == NULL && size != 0) -+ error_msg_and_die(memory_exhausted); -+ return ptr; -+} -+#endif -+ -+static FILE *xfopen(const char *path, const char *mode) - { -- va_list arg_ptr; -- int save = errno; -+ FILE *fp; -+ -+ if ((fp = fopen(path, mode)) == NULL) -+ perror_msg_and_die("%s", path); -+ return fp; -+} - -- fflush(0); -- va_start(arg_ptr, fmt); -- fprintf(stderr, "%s: ", progname); -- vfprintf(stderr, fmt, arg_ptr); -- if (syserr) { -- fprintf(stderr, ": %s", strerror(save)); -+extern int xopen(const char *pathname, int flags, mode_t mode) -+{ -+ int ret; -+ -+ if (flags & O_CREAT) -+ ret = open(pathname, flags, mode); -+ else -+ ret = open(pathname, flags); -+ if (ret == -1) { -+ perror_msg_and_die("%s", pathname); - } -- fprintf(stderr, "\n"); -- va_end(arg_ptr); -- exit(status); -+ return ret; - } - -+extern char *xreadlink(const char *path) -+{ -+ static const int GROWBY = 80; /* how large we will grow strings by */ -+ -+ char *buf = NULL; -+ int bufsize = 0, readsize = 0; -+ -+ do { -+ buf = xrealloc(buf, bufsize += GROWBY); -+ readsize = readlink(path, buf, bufsize); /* 1st try */ -+ if (readsize == -1) { -+ perror_msg("%s:%s", progname, path); -+ return NULL; -+ } -+ } -+ while (bufsize < readsize + 1); -+ -+ buf[readsize] = '\0'; -+ -+ return buf; -+} -+ - static void map_entry(struct entry *entry) - { - if (entry->path) { - entry->fd = open(entry->path, O_RDONLY); - if (entry->fd < 0) { -- die(MKFS_ERROR, 1, "open failed: %s", entry->path); -+ error_msg_and_die("open failed: %s", entry->path); - } - entry->uncompressed = mmap(NULL, entry->size, PROT_READ, MAP_PRIVATE, entry->fd, 0); - if (entry->uncompressed == MAP_FAILED) { -- die(MKFS_ERROR, 1, "mmap failed: %s", entry->path); -+ error_msg_and_die("mmap failed: %s", entry->path); - } - } - } -@@ -174,8 +317,9 @@ - { - if (entry->path) { - if (munmap(entry->uncompressed, entry->size) < 0) { -- die(MKFS_ERROR, 1, "munmap failed: %s", entry->path); -+ error_msg_and_die("munmap failed: %s", entry->path); - } -+ entry->uncompressed=NULL; - close(entry->fd); - } - } -@@ -204,7 +348,8 @@ - find_identical_file(orig->next, newfile)); - } - --static void eliminate_doubles(struct entry *root, struct entry *orig) { -+static void eliminate_doubles(struct entry *root, struct entry *orig) -+{ - if (orig) { - if (orig->size && (orig->path || orig->uncompressed)) - find_identical_file(root, orig); -@@ -232,10 +377,7 @@ - - /* Set up the path. */ - /* TODO: Reuse the parent's buffer to save memcpy'ing and duplication. */ -- path = malloc(len + 1 + MAX_INPUT_NAMELEN + 1); -- if (!path) { -- die(MKFS_ERROR, 1, "malloc failed"); -- } -+ path = xmalloc(len + 1 + MAX_INPUT_NAMELEN + 1); - memcpy(path, name, len); - endpath = path + len; - *endpath = '/'; -@@ -245,7 +387,7 @@ - dircount = scandir(name, &dirlist, 0, cramsort); - - if (dircount < 0) { -- die(MKFS_ERROR, 1, "scandir failed: %s", name); -+ error_msg_and_die("scandir failed: %s", name); - } - - /* process directory */ -@@ -269,25 +411,20 @@ - } - namelen = strlen(dirent->d_name); - if (namelen > MAX_INPUT_NAMELEN) { -- die(MKFS_ERROR, 0, -- "very long (%u bytes) filename found: %s\n" -- "please increase MAX_INPUT_NAMELEN in mkcramfs.c and recompile", -+ error_msg_and_die( -+ "Very long (%u bytes) filename `%s' found.\n" -+ " Please increase MAX_INPUT_NAMELEN in mkcramfs.c and recompile. Exiting.\n", - namelen, dirent->d_name); - } - memcpy(endpath, dirent->d_name, namelen + 1); - - if (lstat(path, &st) < 0) { -+ perror(endpath); - warn_skip = 1; - continue; - } -- entry = calloc(1, sizeof(struct entry)); -- if (!entry) { -- die(MKFS_ERROR, 1, "calloc failed"); -- } -- entry->name = strdup(dirent->d_name); -- if (!entry->name) { -- die(MKFS_ERROR, 1, "strdup failed"); -- } -+ entry = xcalloc(1, sizeof(struct entry)); -+ entry->name = xstrdup(dirent->d_name); - /* truncate multi-byte UTF-8 filenames on character boundary */ - if (namelen > CRAMFS_MAXPATHLEN) { - namelen = CRAMFS_MAXPATHLEN; -@@ -297,24 +434,25 @@ - namelen--; - /* are we reasonably certain it was UTF-8 ? */ - if (entry->name[namelen] < 0x80 || !namelen) { -- die(MKFS_ERROR, 0, "cannot truncate filenames not encoded in UTF-8"); -+ error_msg_and_die("cannot truncate filenames not encoded in UTF-8"); - } - } - entry->name[namelen] = '\0'; - } - entry->mode = st.st_mode; - entry->size = st.st_size; -- entry->uid = st.st_uid; -+ entry->uid = opt_squash ? 0 : st.st_uid; - if (entry->uid >= 1 << CRAMFS_UID_WIDTH) - warn_uid = 1; -- entry->gid = st.st_gid; -- if (entry->gid >= 1 << CRAMFS_GID_WIDTH) -+ entry->gid = opt_squash ? 0 : st.st_gid; -+ if (entry->gid >= 1 << CRAMFS_GID_WIDTH) { - /* TODO: We ought to replace with a default - gid instead of truncating; otherwise there - are security problems. Maybe mode should - be &= ~070. Same goes for uid once Linux - supports >16-bit uids. */ - warn_gid = 1; -+ } - size = sizeof(struct cramfs_inode) + ((namelen + 3) & ~3); - *fslen_ub += size; - if (S_ISDIR(st.st_mode)) { -@@ -325,21 +463,15 @@ - warn_skip = 1; - continue; - } -- entry->path = strdup(path); -- if (!entry->path) { -- die(MKFS_ERROR, 1, "strdup failed"); -- } -+ entry->path = xstrdup(path); - if ((entry->size >= 1 << CRAMFS_SIZE_WIDTH)) { - warn_size = 1; - entry->size = (1 << CRAMFS_SIZE_WIDTH) - 1; - } - } - } else if (S_ISLNK(st.st_mode)) { -- entry->uncompressed = malloc(entry->size); -+ entry->uncompressed = xreadlink(path); - if (!entry->uncompressed) { -- die(MKFS_ERROR, 1, "malloc failed"); -- } -- if (readlink(path, entry->uncompressed, entry->size) < 0) { - warn_skip = 1; - continue; - } -@@ -351,7 +483,7 @@ - if (entry->size & -(1<name); -+ error_msg_and_die("bogus file type: %s", entry->name); - } - - if (S_ISREG(st.st_mode) || S_ISLNK(st.st_mode)) { -@@ -378,7 +510,9 @@ - struct cramfs_super *super = (struct cramfs_super *) base; - unsigned int offset = sizeof(struct cramfs_super) + image_length; - -- offset += opt_pad; /* 0 if no padding */ -+ if (opt_pad) { -+ offset += opt_pad; /* 0 if no padding */ -+ } - - super->magic = CRAMFS_MAGIC; - super->flags = CRAMFS_FLAG_FSID_VERSION_2 | CRAMFS_FLAG_SORTED_DIRS; -@@ -414,10 +548,10 @@ - struct cramfs_inode *inode = (struct cramfs_inode *) (base + entry->dir_offset); - - if ((offset & 3) != 0) { -- die(MKFS_ERROR, 0, "illegal offset of %lu bytes", offset); -+ error_msg_and_die("illegal offset of %lu bytes", offset); - } - if (offset >= (1 << (2 + CRAMFS_OFFSET_WIDTH))) { -- die(MKFS_ERROR, 0, "filesystem too big"); -+ error_msg_and_die("filesystem too big"); - } - inode->offset = (offset >> 2); - } -@@ -429,7 +563,7 @@ - */ - static void print_node(struct entry *e) - { -- char info[10]; -+ char info[12]; - char type = '?'; - - if (S_ISREG(e->mode)) type = 'f'; -@@ -442,11 +576,11 @@ - - if (S_ISCHR(e->mode) || (S_ISBLK(e->mode))) { - /* major/minor numbers can be as high as 2^12 or 4096 */ -- snprintf(info, 10, "%4d,%4d", major(e->size), minor(e->size)); -+ snprintf(info, 11, "%4d,%4d", major(e->size), minor(e->size)); - } - else { - /* size be as high as 2^24 or 16777216 */ -- snprintf(info, 10, "%9d", e->size); -+ snprintf(info, 11, "%9d", e->size); - } - - printf("%c %04o %s %5d:%-3d %s\n", -@@ -462,17 +596,9 @@ - { - int stack_entries = 0; - int stack_size = 64; -- struct entry **entry_stack; -- -- entry_stack = malloc(stack_size * sizeof(struct entry *)); -- if (!entry_stack) { -- die(MKFS_ERROR, 1, "malloc failed"); -- } -- -- if (opt_verbose) { -- printf("root:\n"); -- } -+ struct entry **entry_stack = NULL; - -+ entry_stack = xmalloc(stack_size * sizeof(struct entry *)); - for (;;) { - int dir_start = stack_entries; - while (entry) { -@@ -506,10 +632,7 @@ - if (entry->child) { - if (stack_entries >= stack_size) { - stack_size *= 2; -- entry_stack = realloc(entry_stack, stack_size * sizeof(struct entry *)); -- if (!entry_stack) { -- die(MKFS_ERROR, 1, "realloc failed"); -- } -+ entry_stack = xrealloc(entry_stack, stack_size * sizeof(struct entry *)); - } - entry_stack[stack_entries] = entry; - stack_entries++; -@@ -543,7 +666,7 @@ - - set_data_offset(entry, base, offset); - if (opt_verbose) { -- printf("%s:\n", entry->name); -+ printf("'%s':\n", entry->name); - } - entry = entry->child; - } -@@ -553,16 +676,21 @@ - - static int is_zero(char const *begin, unsigned len) - { -- /* Returns non-zero iff the first LEN bytes from BEGIN are all NULs. */ -- return (len-- == 0 || -- (begin[0] == '\0' && -- (len-- == 0 || -- (begin[1] == '\0' && -- (len-- == 0 || -- (begin[2] == '\0' && -- (len-- == 0 || -- (begin[3] == '\0' && -- memcmp(begin, begin + 4, len) == 0)))))))); -+ if (opt_holes) -+ /* Returns non-zero iff the first LEN bytes from BEGIN are -+ all NULs. */ -+ return (len-- == 0 || -+ (begin[0] == '\0' && -+ (len-- == 0 || -+ (begin[1] == '\0' && -+ (len-- == 0 || -+ (begin[2] == '\0' && -+ (len-- == 0 || -+ (begin[3] == '\0' && -+ memcmp(begin, begin + 4, len) == 0)))))))); -+ else -+ /* Never create holes. */ -+ return 0; - } - - /* -@@ -575,37 +703,34 @@ - * Note that size > 0, as a zero-sized file wouldn't ever - * have gotten here in the first place. - */ --static unsigned int do_compress(char *base, unsigned int offset, char const *name, char *uncompressed, unsigned int size) -+static unsigned int do_compress(char *base, unsigned int offset, struct entry *entry) - { -+ unsigned int size = entry->size; - unsigned long original_size = size; - unsigned long original_offset = offset; - unsigned long new_size; - unsigned long blocks = (size - 1) / blksize + 1; - unsigned long curr = offset + 4 * blocks; - int change; -+ char *uncompressed = entry->uncompressed; - -- total_blocks += blocks; -+ total_blocks += blocks; - - do { - unsigned long len = 2 * blksize; - unsigned int input = size; -- int err; -- - if (input > blksize) - input = blksize; - size -= input; -- if (!(opt_holes && is_zero (uncompressed, input))) { -- err = compress2(base + curr, &len, uncompressed, input, Z_BEST_COMPRESSION); -- if (err != Z_OK) { -- die(MKFS_ERROR, 0, "compression error: %s", zError(err)); -- } -+ if (!is_zero (uncompressed, input)) { -+ compress(base + curr, &len, uncompressed, input); - curr += len; - } - uncompressed += input; - - if (len > blksize*2) { - /* (I don't think this can happen with zlib.) */ -- die(MKFS_ERROR, 0, "AIEEE: block \"compressed\" to > 2*blocklength (%ld)", len); -+ error_msg_and_die("AIEEE: block \"compressed\" to > 2*blocklength (%ld)\n", len); - } - - *(u32 *) (base + offset) = curr; -@@ -618,10 +743,12 @@ - st_blocks * 512. But if you say that then perhaps - administrative data should also be included in both. */ - change = new_size - original_size; -- if (opt_verbose > 1) { -- printf("%6.2f%% (%+d bytes)\t%s\n", -- (change * 100) / (double) original_size, change, name); -+#if 0 -+ if (opt_verbose) { -+ printf("%6.2f%% (%+d bytes)\t%s\n", -+ (change * 100) / (double) original_size, change, entry->name); - } -+#endif - - return curr; - } -@@ -644,7 +771,7 @@ - set_data_offset(entry, base, offset); - entry->offset = offset; - map_entry(entry); -- offset = do_compress(base, offset, entry->name, entry->uncompressed, entry->size); -+ offset = do_compress(base, offset, entry); - unmap_entry(entry); - } - } -@@ -660,13 +787,10 @@ - int fd; - char *buf; - -- fd = open(file, O_RDONLY); -- if (fd < 0) { -- die(MKFS_ERROR, 1, "open failed: %s", file); -- } -+ fd = xopen(file, O_RDONLY, 0); - buf = mmap(NULL, image_length, PROT_READ, MAP_PRIVATE, fd, 0); - if (buf == MAP_FAILED) { -- die(MKFS_ERROR, 1, "mmap failed"); -+ error_msg_and_die("mmap failed"); - } - memcpy(base + offset, buf, image_length); - munmap(buf, image_length); -@@ -679,6 +803,328 @@ - return (offset + image_length); - } - -+static struct entry *find_filesystem_entry(struct entry *dir, char *name, mode_t type) -+{ -+ struct entry *e = dir; -+ -+ if (S_ISDIR(dir->mode)) { -+ e = dir->child; -+ } -+ while (e) { -+ /* Only bother to do the expensive strcmp on matching file types */ -+ if (type == (e->mode & S_IFMT) && e->name) { -+ if (S_ISDIR(e->mode)) { -+ int len = strlen(e->name); -+ -+ /* Check if we are a parent of the correct path */ -+ if (strncmp(e->name, name, len) == 0) { -+ /* Is this an _exact_ match? */ -+ if (strcmp(name, e->name) == 0) { -+ return (e); -+ } -+ /* Looks like we found a parent of the correct path */ -+ if (name[len] == '/') { -+ if (e->child) { -+ return (find_filesystem_entry (e, name + len + 1, type)); -+ } else { -+ return NULL; -+ } -+ } -+ } -+ } else { -+ if (strcmp(name, e->name) == 0) { -+ return (e); -+ } -+ } -+ } -+ e = e->next; -+ } -+ return (NULL); -+} -+ -+void modify_entry(char *full_path, unsigned long uid, unsigned long gid, -+ unsigned long mode, unsigned long rdev, struct entry *root, loff_t *fslen_ub) -+{ -+ char *name, *path, *full; -+ struct entry *curr, *parent, *entry, *prev; -+ -+ full = xstrdup(full_path); -+ path = xstrdup(dirname(full)); -+ name = full_path + strlen(path) + 1; -+ free(full); -+ if (strcmp(path, "/") == 0) { -+ parent = root; -+ name = full_path + 1; -+ } else { -+ if (!(parent = find_filesystem_entry(root, path+1, S_IFDIR))) -+ error_msg_and_die("%s/%s: could not find parent\n", path, name); -+ } -+ if ((entry = find_filesystem_entry(parent, name, (mode & S_IFMT)))) { -+ /* its there, just modify permissions */ -+ entry->mode = mode; -+ entry->uid = uid; -+ entry->gid = gid; -+ } else { /* make a new entry */ -+ -+ /* code partially replicated from parse_directory() */ -+ size_t namelen; -+ if (S_ISREG(mode)) { -+ error_msg_and_die("%s: regular file from device_table file must exist on disk!", full_path); -+ } -+ -+ namelen = strlen(name); -+ if (namelen > MAX_INPUT_NAMELEN) { -+ error_msg_and_die( -+ "Very long (%u bytes) filename `%s' found.\n" -+ " Please increase MAX_INPUT_NAMELEN in mkcramfs.c and recompile. Exiting.\n", -+ namelen, name); -+ } -+ entry = xcalloc(1, sizeof(struct entry)); -+ entry->name = xstrdup(name); -+ /* truncate multi-byte UTF-8 filenames on character boundary */ -+ if (namelen > CRAMFS_MAXPATHLEN) { -+ namelen = CRAMFS_MAXPATHLEN; -+ warn_namelen = 1; -+ /* the first lost byte must not be a trail byte */ -+ while ((entry->name[namelen] & 0xc0) == 0x80) { -+ namelen--; -+ /* are we reasonably certain it was UTF-8 ? */ -+ if (entry->name[namelen] < 0x80 || !namelen) { -+ error_msg_and_die("cannot truncate filenames not encoded in UTF-8"); -+ } -+ } -+ entry->name[namelen] = '\0'; -+ } -+ entry->mode = mode; -+ entry->uid = uid; -+ entry->gid = gid; -+ entry->size = 0; -+ if (S_ISBLK(mode) || S_ISCHR(mode)) { -+ entry->size = rdev; -+ if (entry->size & -(1<size += sizeof(struct cramfs_inode) + ((namelen + 3) & ~3); -+ -+ /* alright, time to link us in */ -+ curr = parent->child; -+ prev = NULL; -+ while (curr && strcmp(name, curr->name) > 0) { -+ prev = curr; -+ curr = curr->next; -+ } -+ if (!prev) parent->child = entry; -+ else prev->next = entry; -+ entry->next = curr; -+ entry->child = NULL; -+ } -+ if (entry->uid >= 1 << CRAMFS_UID_WIDTH) -+ warn_uid = 1; -+ if (entry->gid >= 1 << CRAMFS_GID_WIDTH) { -+ /* TODO: We ought to replace with a default -+ gid instead of truncating; otherwise there -+ are security problems. Maybe mode should -+ be &= ~070. Same goes for uid once Linux -+ supports >16-bit uids. */ -+ warn_gid = 1; -+ } -+ free(path); -+} -+ -+/* the GNU C library has a wonderful scanf("%as", string) which will -+ allocate the string with the right size, good to avoid buffer overruns. -+ the following macros use it if available or use a hacky workaround... -+ */ -+ -+#ifdef __GNUC__ -+#define SCANF_PREFIX "a" -+#define SCANF_STRING(s) (&s) -+#define GETCWD_SIZE 0 -+#else -+#define SCANF_PREFIX "511" -+#define SCANF_STRING(s) (s = xmalloc(512)) -+#define GETCWD_SIZE -1 -+inline int snprintf(char *str, size_t n, const char *fmt, ...) -+{ -+ int ret; -+ va_list ap; -+ -+ va_start(ap, fmt); -+ ret = vsprintf(str, fmt, ap); -+ va_end(ap); -+ return ret; -+} -+#endif -+ -+/* device table entries take the form of: -+ -+ /dev/mem c 640 0 0 1 1 0 0 - -+ -+ type can be one of: -+ f A regular file -+ d Directory -+ c Character special device file -+ b Block special device file -+ p Fifo (named pipe) -+ -+ I don't bother with symlinks (permissions are irrelevant), hard -+ links (special cases of regular files), or sockets (why bother). -+ -+ Regular files must exist in the target root directory. If a char, -+ block, fifo, or directory does not exist, it will be created. -+*/ -+ -+static int interpret_table_entry(char *line, struct entry *root, loff_t *fslen_ub) -+{ -+ char type, *name = NULL; -+ unsigned long mode = 0755, uid = 0, gid = 0, major = 0, minor = 0; -+ unsigned long start = 0, increment = 1, count = 0; -+ -+ if (sscanf (line, "%" SCANF_PREFIX "s %c %lo %lu %lu %lu %lu %lu %lu %lu", -+ SCANF_STRING(name), &type, &mode, &uid, &gid, &major, &minor, -+ &start, &increment, &count) < 0) -+ { -+ return 1; -+ } -+ -+ if (!strcmp(name, "/")) { -+ error_msg_and_die("Device table entries require absolute paths"); -+ } -+ -+ switch (type) { -+ case 'd': -+ mode |= S_IFDIR; -+ modify_entry(name, uid, gid, mode, 0, root, fslen_ub); -+ break; -+ case 'f': -+ mode |= S_IFREG; -+ modify_entry(name, uid, gid, mode, 0, root, fslen_ub); -+ break; -+ case 'p': -+ mode |= S_IFIFO; -+ modify_entry(name, uid, gid, mode, 0, root, fslen_ub); -+ break; -+ case 'c': -+ case 'b': -+ mode |= (type == 'c') ? S_IFCHR : S_IFBLK; -+ if (count > 0) { -+ char *buf; -+ unsigned long i; -+ dev_t rdev; -+ -+ for (i = start; i < count; i++) { -+ asprintf(&buf, "%s%lu", name, i); -+ rdev = makedev(major, minor + (i * increment - start)); -+ modify_entry(buf, uid, gid, mode, rdev, root, fslen_ub); -+ free(buf); -+ } -+ } else { -+ dev_t rdev = makedev(major, minor); -+ modify_entry(name, uid, gid, mode, rdev, root, fslen_ub); -+ } -+ break; -+ default: -+ error_msg_and_die("Unsupported file type"); -+ } -+ free(name); -+ return 0; -+} -+ -+static int parse_device_table(FILE *file, struct entry *root, loff_t *fslen_ub) -+{ -+ char *line; -+ int status = 0; -+ size_t length = 0; -+ -+ /* Turn off squash, since we must ensure that values -+ * entered via the device table are not squashed */ -+ opt_squash = 0; -+ -+ /* Looks ok so far. The general plan now is to read in one -+ * line at a time, check for leading comment delimiters ('#'), -+ * then try and parse the line as a device table. If we fail -+ * to parse things, try and help the poor fool to fix their -+ * device table with a useful error msg... */ -+ line = NULL; -+ while (getline(&line, &length, file) != -1) { -+ /* First trim off any whitespace */ -+ int len = strlen(line); -+ -+ /* trim trailing whitespace */ -+ while (len > 0 && isspace(line[len - 1])) -+ line[--len] = '\0'; -+ /* trim leading whitespace */ -+ memmove(line, &line[strspn(line, " \n\r\t\v")], len); -+ -+ /* How long are we after trimming? */ -+ len = strlen(line); -+ -+ /* If this is NOT a comment line, try to interpret it */ -+ if (len && *line != '#') { -+ if (interpret_table_entry(line, root, fslen_ub)) -+ status = 1; -+ } -+ -+ free(line); -+ line = NULL; -+ } -+ free(line); -+ fclose(file); -+ -+ return status; -+} -+ -+void traverse(struct entry *entry, int depth) -+{ -+ struct entry *curr = entry; -+ int i; -+ -+ while (curr) { -+ for (i = 0; i < depth; i++) putchar(' '); -+ printf("%s: size=%d mode=%d same=%p\n", -+ (curr->name)? (char*)curr->name : "/", -+ curr->size, curr->mode, curr->same); -+ if (curr->child) traverse(curr->child, depth + 4); -+ curr = curr->next; -+ } -+} -+ -+static void free_filesystem_entry(struct entry *dir) -+{ -+ struct entry *e = dir, *last; -+ -+ if (S_ISDIR(dir->mode)) { -+ e = dir->child; -+ } -+ while (e) { -+ if (e->name) -+ free(e->name); -+ if (e->path) -+ free(e->path); -+ if (e->uncompressed) -+ free(e->uncompressed); -+ last = e; -+ if (e->child) { -+ free_filesystem_entry(e); -+ } -+ e = e->next; -+ free(last); -+ } -+} -+ -+ -+/* -+ * Usage: -+ * -+ * mkcramfs directory-name outfile -+ * -+ * where "directory-name" is simply the root of the directory -+ * tree that we want to generate a compressed filesystem out -+ * of. -+ */ - int main(int argc, char **argv) - { - struct stat st; /* used twice... */ -@@ -692,6 +1138,7 @@ - u32 crc; - int c; /* for getopt */ - char *ep; /* for strtoul */ -+ FILE *devtable = NULL; - - total_blocks = 0; - -@@ -699,7 +1146,7 @@ - progname = argv[0]; - - /* command line options */ -- while ((c = getopt(argc, argv, "hEe:i:n:psvz")) != EOF) { -+ while ((c = getopt(argc, argv, "hEe:i:n:psvzD:q")) != EOF) { - switch (c) { - case 'h': - usage(MKFS_OK); -@@ -715,7 +1162,7 @@ - case 'i': - opt_image = optarg; - if (lstat(opt_image, &st) < 0) { -- die(MKFS_ERROR, 1, "lstat failed: %s", opt_image); -+ error_msg_and_die("lstat failed: %s", opt_image); - } - image_length = st.st_size; /* may be padded later */ - fslen_ub += (image_length + 3); /* 3 is for padding */ -@@ -736,6 +1183,16 @@ - case 'z': - opt_holes = 1; - break; -+ case 'q': -+ opt_squash = 1; -+ break; -+ case 'D': -+ devtable = xfopen(optarg, "r"); -+ if (fstat(fileno(devtable), &st) < 0) -+ perror_msg_and_die(optarg); -+ if (st.st_size < 10) -+ error_msg_and_die("%s: not a proper device table file\n", optarg); -+ break; - } - } - -@@ -745,25 +1202,23 @@ - outfile = argv[optind + 1]; - - if (stat(dirname, &st) < 0) { -- die(MKFS_USAGE, 1, "stat failed: %s", dirname); -- } -- fd = open(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666); -- if (fd < 0) { -- die(MKFS_USAGE, 1, "open failed: %s", outfile); -+ error_msg_and_die("stat failed: %s", dirname); - } -+ fd = xopen(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666); - -- root_entry = calloc(1, sizeof(struct entry)); -- if (!root_entry) { -- die(MKFS_ERROR, 1, "calloc failed"); -- } -+ root_entry = xcalloc(1, sizeof(struct entry)); - root_entry->mode = st.st_mode; - root_entry->uid = st.st_uid; - root_entry->gid = st.st_gid; - - root_entry->size = parse_directory(root_entry, dirname, &root_entry->child, &fslen_ub); - -+ if (devtable) { -+ parse_device_table(devtable, root_entry, &fslen_ub); -+ } -+ - /* always allocate a multiple of blksize bytes because that's -- what we're going to write later on */ -+ what we're going to write later on */ - fslen_ub = ((fslen_ub - 1) | (blksize - 1)) + 1; - - if (fslen_ub > MAXFSLEN) { -@@ -790,7 +1245,7 @@ - rom_image = mmap(NULL, fslen_ub?fslen_ub:1, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - if (rom_image == MAP_FAILED) { -- die(MKFS_ERROR, 1, "mmap failed"); -+ error_msg_and_die("mmap failed"); - } - - /* Skip the first opt_pad bytes for boot loader code */ -@@ -807,6 +1262,7 @@ - } - - offset = write_directory_structure(root_entry->child, rom_image, offset); -+ if (opt_verbose) - printf("Directory data: %d bytes\n", offset); - - offset = write_data(root_entry, rom_image, offset); -@@ -814,30 +1270,38 @@ - /* We always write a multiple of blksize bytes, so that - losetup works. */ - offset = ((offset - 1) | (blksize - 1)) + 1; -+ if (opt_verbose) - printf("Everything: %d kilobytes\n", offset >> 10); - - /* Write the superblock now that we can fill in all of the fields. */ - write_superblock(root_entry, rom_image+opt_pad, offset); -+ if (opt_verbose) - printf("Super block: %d bytes\n", sizeof(struct cramfs_super)); - - /* Put the checksum in. */ - crc = crc32(0L, Z_NULL, 0); - crc = crc32(crc, (rom_image+opt_pad), (offset-opt_pad)); - ((struct cramfs_super *) (rom_image+opt_pad))->fsid.crc = crc; -+ if (opt_verbose) - printf("CRC: %x\n", crc); - - /* Check to make sure we allocated enough space. */ - if (fslen_ub < offset) { -- die(MKFS_ERROR, 0, "not enough space allocated for ROM image (%Ld allocated, %d used)", fslen_ub, offset); -+ error_msg_and_die("not enough space allocated for ROM " -+ "image (%Ld allocated, %d used)", fslen_ub, offset); - } - - written = write(fd, rom_image, offset); - if (written < 0) { -- die(MKFS_ERROR, 1, "write failed"); -+ error_msg_and_die("write failed"); - } - if (offset != written) { -- die(MKFS_ERROR, 0, "ROM image write failed (wrote %d of %d bytes)", written, offset); -+ error_msg_and_die("ROM image write failed (wrote %d of %d bytes)", written, offset); - } -+ -+ /* Free up memory */ -+ free_filesystem_entry(root_entry); -+ free(root_entry); - - /* (These warnings used to come at the start, but they scroll off the - screen too quickly.) */ diff --git a/obsolete-buildroot/sources/device_table.txt b/obsolete-buildroot/sources/device_table.txt deleted file mode 100644 index 75d8068354..0000000000 --- a/obsolete-buildroot/sources/device_table.txt +++ /dev/null @@ -1,163 +0,0 @@ -# When building a target filesystem, it is desirable to not have to -# become root and then run 'mknod' a thousand times. Using a device -# table you can create device nodes and directories "on the fly". -# -# This is a sample device table file for use with genext2fs. You can -# do all sorts of interesting things with a device table file. For -# example, if you want to adjust the permissions on a particular file -# you can just add an entry like: -# /sbin/foobar f 2755 0 0 - - - - - -# and (assuming the file /sbin/foobar exists) it will be made setuid -# root (regardless of what its permissions are on the host filesystem. -# Furthermore, you can use a single table entry to create a many device -# minors. For example, if I wanted to create /dev/hda and /dev/hda[0-15] -# I could just use the following two table entries: -# /dev/hda b 640 0 0 3 0 0 0 - -# /dev/hda b 640 0 0 3 1 1 1 15 -# -# Device table entries take the form of: -# -# where name is the file name, type can be one of: -# f A regular file -# d Directory -# c Character special device file -# b Block special device file -# p Fifo (named pipe) -# uid is the user id for the target file, gid is the group id for the -# target file. The rest of the entries (major, minor, etc) apply only -# to device special files. - -# Have fun -# -Erik Andersen -# - -# -/dev d 755 0 0 - - - - - -/dev d 755 0 0 - - - - - -/dev/pts d 755 0 0 - - - - - -/tmp d 1777 0 0 - - - - - -/etc d 755 0 0 - - - - - -/home/default d 2755 1000 1000 - - - - - -/etc/network/if-up.d d 755 0 0 - - - - - -/etc/network/if-pre-up.d d 755 0 0 - - - - - -/etc/network/if-down.d d 755 0 0 - - - - - -/etc/network/if-post-down.d d 755 0 0 - - - - - -# Adjust permissions on some normal files -/etc/shadow f 600 0 0 - - - - - -/etc/passwd f 644 0 0 - - - - - -/bin/busybox f 4755 0 0 - - - - - -# uncomment this to allow starting x as non-root -#/usr/X11R6/bin/Xfbdev f 4755 0 0 - - - - - - -# Normal system devices -/dev/mem c 640 0 0 1 1 0 0 - -/dev/kmem c 640 0 0 1 2 0 0 - -/dev/null c 666 0 0 1 3 0 0 - -/dev/zero c 666 0 0 1 5 0 0 - -/dev/random c 666 0 0 1 8 0 0 - -/dev/urandom c 666 0 0 1 9 0 0 - -/dev/ram b 640 0 0 1 1 0 0 - -/dev/ram b 640 0 0 1 0 0 1 4 -/dev/loop b 640 0 0 7 0 0 1 2 -/dev/rtc c 640 0 0 10 135 - - - -/dev/console c 666 0 0 5 1 - - - -/dev/tty c 666 0 0 5 0 - - - -/dev/tty c 666 0 0 4 0 0 1 8 -/dev/ttyp c 666 0 0 3 0 0 1 10 -/dev/ptyp c 666 0 0 2 0 0 1 10 -/dev/ptmx c 666 0 0 5 2 - - - -/dev/ttyP c 666 0 0 57 0 0 1 4 -/dev/ttyS c 666 0 0 4 64 0 1 4 -/dev/fb c 640 0 5 29 0 0 32 4 -#/dev/ttySA c 666 0 0 204 5 0 1 3 -/dev/psaux c 666 0 0 10 1 0 0 - -#/dev/ppp c 666 0 0 108 0 - - - - -# MTD stuff -/dev/mtd c 640 0 0 90 0 0 2 4 -/dev/mtdblock b 640 0 0 31 0 0 1 4 - -#Tun/tap driver -/dev/net d 755 0 0 - - - - - -/dev/net/tun c 660 0 0 10 200 - - - - -# Audio stuff -#/dev/audio c 666 0 29 14 4 - - - -#/dev/audio1 c 666 0 29 14 20 - - - -#/dev/dsp c 666 0 29 14 3 - - - -#/dev/dsp1 c 666 0 29 14 19 - - - -#/dev/sndstat c 666 0 29 14 6 - - - - -# User-mode Linux stuff -/dev/ubda b 640 0 0 98 0 0 0 - -/dev/ubda b 640 0 0 98 1 1 1 15 - -# IDE Devices -/dev/hda b 640 0 0 3 0 0 0 - -/dev/hda b 640 0 0 3 1 1 1 15 -/dev/hdb b 640 0 0 3 64 0 0 - -/dev/hdb b 640 0 0 3 65 1 1 15 -#/dev/hdc b 640 0 0 22 0 0 0 - -#/dev/hdc b 640 0 0 22 1 1 1 15 -#/dev/hdd b 640 0 0 22 64 0 0 - -#/dev/hdd b 640 0 0 22 65 1 1 15 -#/dev/hde b 640 0 0 33 0 0 0 - -#/dev/hde b 640 0 0 33 1 1 1 15 -#/dev/hdf b 640 0 0 33 64 0 0 - -#/dev/hdf b 640 0 0 33 65 1 1 15 -#/dev/hdg b 640 0 0 34 0 0 0 - -#/dev/hdg b 640 0 0 34 1 1 1 15 -#/dev/hdh b 640 0 0 34 64 0 0 - -#/dev/hdh b 640 0 0 34 65 1 1 15 - -# SCSI Devices -#/dev/sda b 640 0 0 8 0 0 0 - -#/dev/sda b 640 0 0 8 1 1 1 15 -#/dev/sdb b 640 0 0 8 16 0 0 - -#/dev/sdb b 640 0 0 8 17 1 1 15 -#/dev/sdc b 640 0 0 8 32 0 0 - -#/dev/sdc b 640 0 0 8 33 1 1 15 -#/dev/sdd b 640 0 0 8 48 0 0 - -#/dev/sdd b 640 0 0 8 49 1 1 15 -#/dev/sde b 640 0 0 8 64 0 0 - -#/dev/sde b 640 0 0 8 65 1 1 15 -#/dev/sdf b 640 0 0 8 80 0 0 - -#/dev/sdf b 640 0 0 8 81 1 1 15 -#/dev/sdg b 640 0 0 8 96 0 0 - -#/dev/sdg b 640 0 0 8 97 1 1 15 -#/dev/sdh b 640 0 0 8 112 0 0 - -#/dev/sdh b 640 0 0 8 113 1 1 15 -#/dev/sg c 640 0 0 21 0 0 1 15 -#/dev/scd b 640 0 0 11 0 0 1 15 -#/dev/st c 640 0 0 9 0 0 1 8 -#/dev/nst c 640 0 0 9 128 0 1 8 -#/dev/st c 640 0 0 9 32 1 1 4 -#/dev/st c 640 0 0 9 64 1 1 4 -#/dev/st c 640 0 0 9 96 1 1 4 - -# Floppy disk devices -#/dev/fd b 640 0 0 2 0 0 1 2 -#/dev/fd0d360 b 640 0 0 2 4 0 0 - -#/dev/fd1d360 b 640 0 0 2 5 0 0 - -#/dev/fd0h1200 b 640 0 0 2 8 0 0 - -#/dev/fd1h1200 b 640 0 0 2 9 0 0 - -#/dev/fd0u1440 b 640 0 0 2 28 0 0 - -#/dev/fd1u1440 b 640 0 0 2 29 0 0 - -#/dev/fd0u2880 b 640 0 0 2 32 0 0 - -#/dev/fd1u2880 b 640 0 0 2 33 0 0 - - -# All the proprietary cdrom devices in the world -#/dev/aztcd b 640 0 0 29 0 0 0 - -#/dev/bpcd b 640 0 0 41 0 0 0 - -#/dev/capi20 c 640 0 0 68 0 0 1 2 -#/dev/cdu31a b 640 0 0 15 0 0 0 - -#/dev/cdu535 b 640 0 0 24 0 0 0 - -#/dev/cm206cd b 640 0 0 32 0 0 0 - -#/dev/sjcd b 640 0 0 18 0 0 0 - -#/dev/sonycd b 640 0 0 15 0 0 0 - -#/dev/gscd b 640 0 0 16 0 0 0 - -#/dev/sbpcd b 640 0 0 25 0 0 0 - -#/dev/sbpcd b 640 0 0 25 0 0 1 4 -#/dev/mcd b 640 0 0 23 0 0 0 - -#/dev/optcd b 640 0 0 17 0 0 0 - - diff --git a/obsolete-buildroot/sources/dnsmasq1-openwrt.patch b/obsolete-buildroot/sources/dnsmasq1-openwrt.patch deleted file mode 100644 index e1741a28a2..0000000000 --- a/obsolete-buildroot/sources/dnsmasq1-openwrt.patch +++ /dev/null @@ -1,219 +0,0 @@ -diff -x CVS -urN dnsmasq-1.18/dhcp.c dnsmasq.old/dhcp.c ---- dnsmasq-1.18/dhcp.c 2003-11-05 08:30:20.000000000 -0600 -+++ dnsmasq.old/dhcp.c 2004-01-05 23:40:11.000000000 -0600 -@@ -15,14 +15,20 @@ - - #include "dnsmasq.h" - --static int next_token (char *token, int buffsize, FILE * fp); -+struct dhcpOfferedAddr { -+ u_int8_t hostname[16]; -+ u_int8_t chaddr[16]; -+ u_int32_t yiaddr; /* network order */ -+ u_int32_t expires; /* host order */ -+}; - - void load_dhcp(char *file, char *suffix, time_t now, char *hostname) - { -- char token[MAXTOK], *dot; -+ char *dot; - struct all_addr host_address; -- time_t ttd, tts; -+ time_t ttd; - FILE *fp = fopen (file, "r"); -+ struct dhcpOfferedAddr lease; - - if (!fp) - { -@@ -34,154 +40,45 @@ - - /* remove all existing DHCP cache entries */ - cache_unhash_dhcp(); -- -- while ((next_token(token, MAXTOK, fp))) -- { -- if (strcmp(token, "lease") == 0) -- { -- hostname[0] = '\0'; -- ttd = tts = (time_t)(-1); --#ifdef HAVE_IPV6 -- if (next_token(token, MAXTOK, fp) && -- inet_pton(AF_INET, token, &host_address)) --#else -- if (next_token(token, MAXTOK, fp) && -- (host_address.addr4.s_addr = inet_addr(token)) != (in_addr_t) -1) --#endif -- { -- if (next_token(token, MAXTOK, fp) && *token == '{') -- { -- while (next_token(token, MAXTOK, fp) && *token != '}') -+ -+ while (fread(&lease, sizeof(lease), 1, fp)) { -+ host_address.addr.addr4.s_addr = lease.yiaddr; -+ -+ strcpy(hostname,lease.hostname); -+ if (lease.expires>(unsigned)now) -+ ttd = lease.expires; -+ else -+ ttd = -1; -+ dot = strchr(hostname, '.'); -+ if (suffix) - { -- if ((strcmp(token, "client-hostname") == 0) || -- (strcmp(token, "hostname") == 0)) -- { -- if (next_token(hostname, MAXDNAME, fp)) -- if (!canonicalise(hostname)) -- { -- *hostname = 0; -- syslog(LOG_ERR, "bad name in %s", file); -- } -- } -- else if ((strcmp(token, "ends") == 0) || -- (strcmp(token, "starts") == 0)) -- { -- struct tm lease_time; -- int is_ends = (strcmp(token, "ends") == 0); -- if (next_token(token, MAXTOK, fp) && /* skip weekday */ -- next_token(token, MAXTOK, fp) && /* Get date from lease file */ -- sscanf (token, "%d/%d/%d", -- &lease_time.tm_year, -- &lease_time.tm_mon, -- &lease_time.tm_mday) == 3 && -- next_token(token, MAXTOK, fp) && -- sscanf (token, "%d:%d:%d:", -- &lease_time.tm_hour, -- &lease_time.tm_min, -- &lease_time.tm_sec) == 3) -- { -- /* There doesn't seem to be a universally available library function -- which converts broken-down _GMT_ time to seconds-in-epoch. -- The following was borrowed from ISC dhcpd sources, where -- it is noted that it might not be entirely accurate for odd seconds. -- Since we're trying to get the same answer as dhcpd, that's just -- fine here. */ -- static int months [11] = { 31, 59, 90, 120, 151, 181, -- 212, 243, 273, 304, 334 }; -- time_t time = ((((((365 * (lease_time.tm_year - 1970) + /* Days in years since '70 */ -- (lease_time.tm_year - 1969) / 4 + /* Leap days since '70 */ -- (lease_time.tm_mon > 1 /* Days in months this year */ -- ? months [lease_time.tm_mon - 2] -- : 0) + -- (lease_time.tm_mon > 2 && /* Leap day this year */ -- !((lease_time.tm_year - 1972) & 3)) + -- lease_time.tm_mday - 1) * 24) + /* Day of month */ -- lease_time.tm_hour) * 60) + -- lease_time.tm_min) * 60) + lease_time.tm_sec; -- if (is_ends) -- ttd = time; -- else -- tts = time; } -+ if (dot) -+ { /* suffix and lease has ending: must match */ -+ if (strcmp(dot+1, suffix) != 0) -+ syslog(LOG_WARNING, -+ "Ignoring DHCP lease for %s because it has an illegal domain part", hostname); -+ else -+ cache_add_dhcp_entry(hostname, &host_address, ttd, F_REVERSE); - } -- } -- -- /* missing info? */ -- if (!*hostname) -- continue; -- if (ttd == (time_t)(-1)) -- continue; -- -- /* infinite lease to is represented by -1 */ -- /* This makes is to the lease file as -- start time one less than end time. */ -- /* We use -1 as infinite in ttd */ -- if ((tts != -1) && (ttd == tts - 1)) -- ttd = (time_t)(-1); -- else if (ttd < now) -- continue; -- -- dot = strchr(hostname, '.'); -- if (suffix) -- { -- if (dot) -- { /* suffix and lease has ending: must match */ -- if (strcmp(dot+1, suffix) != 0) -- syslog(LOG_WARNING, -- "Ignoring DHCP lease for %s because it has an illegal domain part", hostname); -- else -- cache_add_dhcp_entry(hostname, &host_address, ttd, F_REVERSE); -- } -- else -- { /* suffix exists but lease has no ending - add lease and lease.suffix */ -- cache_add_dhcp_entry(hostname, &host_address, ttd, 0); -- strncat(hostname, ".", MAXDNAME); -- strncat(hostname, suffix, MAXDNAME); -- hostname[MAXDNAME-1] = 0; /* in case strncat hit limit */ -- /* Make FQDN canonical for reverse lookups */ -- cache_add_dhcp_entry(hostname, &host_address, ttd, F_REVERSE); -- } -- } -- else -- { /* no suffix */ -- if (dot) /* no lease ending allowed */ -- syslog(LOG_WARNING, -- "Ignoring DHCP lease for %s because it has a domain part", hostname); -- else -- cache_add_dhcp_entry(hostname, &host_address, ttd, F_REVERSE); -- } -- } -- } -- } -- } -+ else -+ { /* suffix exists but lease has no ending - add lease and lease.suffix */ -+ cache_add_dhcp_entry(hostname, &host_address, ttd, 0); -+ strncat(hostname, ".", MAXDNAME); -+ strncat(hostname, suffix, MAXDNAME); -+ hostname[MAXDNAME-1] = 0; /* in case strncat hit limit */ -+ /* Make FQDN canonical for reverse lookups */ -+ cache_add_dhcp_entry(hostname, &host_address, ttd, F_REVERSE); -+ } -+ } -+ else -+ { /* no suffix */ -+ if (dot) /* no lease ending allowed */ -+ syslog(LOG_WARNING, -+ "Ignoring DHCP lease for %s because it has a domain part", hostname); -+ else -+ cache_add_dhcp_entry(hostname, &host_address, ttd, F_REVERSE); -+ } -+ } - fclose(fp); - - } -- --static int next_token (char *token, int buffsize, FILE * fp) --{ -- int c, count = 0; -- char *cp = token; -- -- while((c = getc(fp)) != EOF) -- { -- if (c == '#') -- do { c = getc(fp); } while (c != '\n' && c != EOF); -- -- if (c == ' ' || c == '\t' || c == '\n' || c == ';') -- { -- if (count) -- break; -- } -- else if ((c != '"') && (count 2003 -+ * -+ * Write-once-read-many hash table, used for checking if a given -+ * MAC address belongs to a set or not and possibly for checking -+ * if it is related with a given IPv4 address. -+ * -+ * The hash value of an address is its last byte. -+ * -+ * In real-world ethernet addresses, values of the last byte are -+ * evenly distributed and there is no need to consider other bytes. -+ * It would only slow the routines down. -+ * -+ * For MAC address comparison speedup reasons, we introduce a trick. -+ * MAC address is mapped onto an array of two 32-bit integers. -+ * This pair of integers is compared with MAC addresses in the -+ * hash table, which are stored also in form of pairs of integers -+ * (in `cmp' array). This is quick as it requires only two elementary -+ * number comparisons in worst case. Further, we take advantage of -+ * fact that entropy of 3 last bytes of address is larger than entropy -+ * of 3 first bytes. So first we compare 4 last bytes of addresses and -+ * if they are the same we compare 2 first. -+ * -+ * Yes, it is a memory overhead, but in 2003 AD, who cares? -+ */ -+ -+struct ebt_mac_wormhash_tuple -+{ -+ uint32_t cmp[2]; -+ uint32_t ip; -+}; -+ -+struct ebt_mac_wormhash -+{ -+ int table[257]; -+ int poolsize; -+ struct ebt_mac_wormhash_tuple pool[0]; -+}; -+ -+#define ebt_mac_wormhash_size(x) ((x) ? sizeof(struct ebt_mac_wormhash) \ -+ + (x)->poolsize * sizeof(struct ebt_mac_wormhash_tuple) : 0) -+ -+struct ebt_among_info -+{ -+ int wh_dst_ofs; -+ int wh_src_ofs; -+ int bitmask; -+}; -+ -+#define EBT_AMONG_DST_NEG 0x1 -+#define EBT_AMONG_SRC_NEG 0x2 -+ -+#define ebt_among_wh_dst(x) ((x)->wh_dst_ofs ? \ -+ (struct ebt_mac_wormhash*)((char*)(x) + (x)->wh_dst_ofs) : NULL) -+#define ebt_among_wh_src(x) ((x)->wh_src_ofs ? \ -+ (struct ebt_mac_wormhash*)((char*)(x) + (x)->wh_src_ofs) : NULL) -+ -+#define EBT_AMONG_MATCH "among" -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_arp.h src/linux/linux/include/linux/netfilter_bridge/ebt_arp.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_arp.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_arp.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,32 @@ -+#ifndef __LINUX_BRIDGE_EBT_ARP_H -+#define __LINUX_BRIDGE_EBT_ARP_H -+ -+#define EBT_ARP_OPCODE 0x01 -+#define EBT_ARP_HTYPE 0x02 -+#define EBT_ARP_PTYPE 0x04 -+#define EBT_ARP_SRC_IP 0x08 -+#define EBT_ARP_DST_IP 0x10 -+#define EBT_ARP_SRC_MAC 0x20 -+#define EBT_ARP_DST_MAC 0x40 -+#define EBT_ARP_MASK (EBT_ARP_OPCODE | EBT_ARP_HTYPE | EBT_ARP_PTYPE | \ -+ EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC) -+#define EBT_ARP_MATCH "arp" -+ -+struct ebt_arp_info -+{ -+ uint16_t htype; -+ uint16_t ptype; -+ uint16_t opcode; -+ uint32_t saddr; -+ uint32_t smsk; -+ uint32_t daddr; -+ uint32_t dmsk; -+ unsigned char smaddr[ETH_ALEN]; -+ unsigned char smmsk[ETH_ALEN]; -+ unsigned char dmaddr[ETH_ALEN]; -+ unsigned char dmmsk[ETH_ALEN]; -+ uint8_t bitmask; -+ uint8_t invflags; -+}; -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_arpreply.h src/linux/linux/include/linux/netfilter_bridge/ebt_arpreply.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_arpreply.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_arpreply.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,11 @@ -+#ifndef __LINUX_BRIDGE_EBT_ARPREPLY_H -+#define __LINUX_BRIDGE_EBT_ARPREPLY_H -+ -+struct ebt_arpreply_info -+{ -+ unsigned char mac[ETH_ALEN]; -+ int target; -+}; -+#define EBT_ARPREPLY_TARGET "arpreply" -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_ip.h src/linux/linux/include/linux/netfilter_bridge/ebt_ip.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_ip.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_ip.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,43 @@ -+/* -+ * ebt_ip -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * April, 2002 -+ * -+ * Changes: -+ * added ip-sport and ip-dport -+ * Innominate Security Technologies AG -+ * September, 2002 -+ */ -+ -+#ifndef __LINUX_BRIDGE_EBT_IP_H -+#define __LINUX_BRIDGE_EBT_IP_H -+ -+#define EBT_IP_SOURCE 0x01 -+#define EBT_IP_DEST 0x02 -+#define EBT_IP_TOS 0x04 -+#define EBT_IP_PROTO 0x08 -+#define EBT_IP_SPORT 0x10 -+#define EBT_IP_DPORT 0x20 -+#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\ -+ EBT_IP_SPORT | EBT_IP_DPORT ) -+#define EBT_IP_MATCH "ip" -+ -+// the same values are used for the invflags -+struct ebt_ip_info -+{ -+ uint32_t saddr; -+ uint32_t daddr; -+ uint32_t smsk; -+ uint32_t dmsk; -+ uint8_t tos; -+ uint8_t protocol; -+ uint8_t bitmask; -+ uint8_t invflags; -+ uint16_t sport[2]; -+ uint16_t dport[2]; -+}; -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_limit.h src/linux/linux/include/linux/netfilter_bridge/ebt_limit.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_limit.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_limit.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,23 @@ -+#ifndef __LINUX_BRIDGE_EBT_LIMIT_H -+#define __LINUX_BRIDGE_EBT_LIMIT_H -+ -+#define EBT_LIMIT_MATCH "limit" -+ -+/* timings are in milliseconds. */ -+#define EBT_LIMIT_SCALE 10000 -+ -+/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 -+ seconds, or one every 59 hours. */ -+ -+struct ebt_limit_info -+{ -+ u_int32_t avg; /* Average secs between packets * scale */ -+ u_int32_t burst; /* Period multiplier for upper limit. */ -+ -+ /* Used internally by the kernel */ -+ unsigned long prev; -+ u_int32_t credit; -+ u_int32_t credit_cap, cost; -+}; -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_log.h src/linux/linux/include/linux/netfilter_bridge/ebt_log.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_log.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_log.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,17 @@ -+#ifndef __LINUX_BRIDGE_EBT_LOG_H -+#define __LINUX_BRIDGE_EBT_LOG_H -+ -+#define EBT_LOG_IP 0x01 // if the frame is made by ip, log the ip information -+#define EBT_LOG_ARP 0x02 -+#define EBT_LOG_MASK (EBT_LOG_IP | EBT_LOG_ARP) -+#define EBT_LOG_PREFIX_SIZE 30 -+#define EBT_LOG_WATCHER "log" -+ -+struct ebt_log_info -+{ -+ uint8_t loglevel; -+ uint8_t prefix[EBT_LOG_PREFIX_SIZE]; -+ uint32_t bitmask; -+}; -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_mark_m.h src/linux/linux/include/linux/netfilter_bridge/ebt_mark_m.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_mark_m.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_mark_m.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,15 @@ -+#ifndef __LINUX_BRIDGE_EBT_MARK_M_H -+#define __LINUX_BRIDGE_EBT_MARK_M_H -+ -+#define EBT_MARK_AND 0x01 -+#define EBT_MARK_OR 0x02 -+#define EBT_MARK_MASK (EBT_MARK_AND | EBT_MARK_OR) -+struct ebt_mark_m_info -+{ -+ unsigned long mark, mask; -+ uint8_t invert; -+ uint8_t bitmask; -+}; -+#define EBT_MARK_MATCH "mark_m" -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_mark_t.h src/linux/linux/include/linux/netfilter_bridge/ebt_mark_t.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_mark_t.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_mark_t.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,12 @@ -+#ifndef __LINUX_BRIDGE_EBT_MARK_T_H -+#define __LINUX_BRIDGE_EBT_MARK_T_H -+ -+struct ebt_mark_t_info -+{ -+ unsigned long mark; -+ // EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN -+ int target; -+}; -+#define EBT_MARK_TARGET "mark" -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_nat.h src/linux/linux/include/linux/netfilter_bridge/ebt_nat.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_nat.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_nat.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,13 @@ -+#ifndef __LINUX_BRIDGE_EBT_NAT_H -+#define __LINUX_BRIDGE_EBT_NAT_H -+ -+struct ebt_nat_info -+{ -+ unsigned char mac[ETH_ALEN]; -+ // EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN -+ int target; -+}; -+#define EBT_SNAT_TARGET "snat" -+#define EBT_DNAT_TARGET "dnat" -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_pkttype.h src/linux/linux/include/linux/netfilter_bridge/ebt_pkttype.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_pkttype.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_pkttype.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,11 @@ -+#ifndef __LINUX_BRIDGE_EBT_PKTTYPE_H -+#define __LINUX_BRIDGE_EBT_PKTTYPE_H -+ -+struct ebt_pkttype_info -+{ -+ uint8_t pkt_type; -+ uint8_t invert; -+}; -+#define EBT_PKTTYPE_MATCH "pkttype" -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_redirect.h src/linux/linux/include/linux/netfilter_bridge/ebt_redirect.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_redirect.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_redirect.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,11 @@ -+#ifndef __LINUX_BRIDGE_EBT_REDIRECT_H -+#define __LINUX_BRIDGE_EBT_REDIRECT_H -+ -+struct ebt_redirect_info -+{ -+ // EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN -+ int target; -+}; -+#define EBT_REDIRECT_TARGET "redirect" -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_stp.h src/linux/linux/include/linux/netfilter_bridge/ebt_stp.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_stp.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_stp.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,46 @@ -+#ifndef __LINUX_BRIDGE_EBT_STP_H -+#define __LINUX_BRIDGE_EBT_STP_H -+ -+#define EBT_STP_TYPE 0x0001 -+ -+#define EBT_STP_FLAGS 0x0002 -+#define EBT_STP_ROOTPRIO 0x0004 -+#define EBT_STP_ROOTADDR 0x0008 -+#define EBT_STP_ROOTCOST 0x0010 -+#define EBT_STP_SENDERPRIO 0x0020 -+#define EBT_STP_SENDERADDR 0x0040 -+#define EBT_STP_PORT 0x0080 -+#define EBT_STP_MSGAGE 0x0100 -+#define EBT_STP_MAXAGE 0x0200 -+#define EBT_STP_HELLOTIME 0x0400 -+#define EBT_STP_FWDD 0x0800 -+ -+#define EBT_STP_MASK 0x0fff -+#define EBT_STP_CONFIG_MASK 0x0ffe -+ -+#define EBT_STP_MATCH "stp" -+ -+struct ebt_stp_config_info -+{ -+ uint8_t flags; -+ uint16_t root_priol, root_priou; -+ char root_addr[6], root_addrmsk[6]; -+ uint32_t root_costl, root_costu; -+ uint16_t sender_priol, sender_priou; -+ char sender_addr[6], sender_addrmsk[6]; -+ uint16_t portl, portu; -+ uint16_t msg_agel, msg_ageu; -+ uint16_t max_agel, max_ageu; -+ uint16_t hello_timel, hello_timeu; -+ uint16_t forward_delayl, forward_delayu; -+}; -+ -+struct ebt_stp_info -+{ -+ uint8_t type; -+ struct ebt_stp_config_info config; -+ uint16_t bitmask; -+ uint16_t invflags; -+}; -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_vlan.h src/linux/linux/include/linux/netfilter_bridge/ebt_vlan.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_vlan.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebt_vlan.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,20 @@ -+#ifndef __LINUX_BRIDGE_EBT_VLAN_H -+#define __LINUX_BRIDGE_EBT_VLAN_H -+ -+#define EBT_VLAN_ID 0x01 -+#define EBT_VLAN_PRIO 0x02 -+#define EBT_VLAN_ENCAP 0x04 -+#define EBT_VLAN_MASK (EBT_VLAN_ID | EBT_VLAN_PRIO | EBT_VLAN_ENCAP) -+#define EBT_VLAN_MATCH "vlan" -+ -+struct ebt_vlan_info { -+ uint16_t id; /* VLAN ID {1-4095} */ -+ uint8_t prio; /* VLAN User Priority {0-7} */ -+ uint16_t encap; /* VLAN Encapsulated frame code {0-65535} */ -+ uint8_t bitmask; /* Args bitmask bit 1=1 - ID arg, -+ bit 2=1 User-Priority arg, bit 3=1 encap*/ -+ uint8_t invflags; /* Inverse bitmask bit 1=1 - inversed ID arg, -+ bit 2=1 - inversed Pirority arg */ -+}; -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebtables.h src/linux/linux/include/linux/netfilter_bridge/ebtables.h ---- src/linux/linux.stock/include/linux/netfilter_bridge/ebtables.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_bridge/ebtables.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,361 @@ -+/* -+ * ebtables -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * ebtables.c,v 2.0, September, 2002 -+ * -+ * This code is stongly inspired on the iptables code which is -+ * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling -+ */ -+ -+#ifndef __LINUX_BRIDGE_EFF_H -+#define __LINUX_BRIDGE_EFF_H -+#include -+#include -+#include -+ -+#define EBT_TABLE_MAXNAMELEN 32 -+#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN -+#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN -+ -+// verdicts >0 are "branches" -+#define EBT_ACCEPT -1 -+#define EBT_DROP -2 -+#define EBT_CONTINUE -3 -+#define EBT_RETURN -4 -+#define NUM_STANDARD_TARGETS 4 -+ -+struct ebt_counter -+{ -+ uint64_t pcnt; -+ uint64_t bcnt; -+}; -+ -+struct ebt_entries { -+ // this field is always set to zero -+ // See EBT_ENTRY_OR_ENTRIES. -+ // Must be same size as ebt_entry.bitmask -+ unsigned int distinguisher; -+ // the chain name -+ char name[EBT_CHAIN_MAXNAMELEN]; -+ // counter offset for this chain -+ unsigned int counter_offset; -+ // one standard (accept, drop, return) per hook -+ int policy; -+ // nr. of entries -+ unsigned int nentries; -+ // entry list -+ char data[0]; -+}; -+ -+// used for the bitmask of struct ebt_entry -+ -+// This is a hack to make a difference between an ebt_entry struct and an -+// ebt_entries struct when traversing the entries from start to end. -+// Using this simplifies the code alot, while still being able to use -+// ebt_entries. -+// Contrary, iptables doesn't use something like ebt_entries and therefore uses -+// different techniques for naming the policy and such. So, iptables doesn't -+// need a hack like this. -+#define EBT_ENTRY_OR_ENTRIES 0x01 -+// these are the normal masks -+#define EBT_NOPROTO 0x02 -+#define EBT_802_3 0x04 -+#define EBT_SOURCEMAC 0x08 -+#define EBT_DESTMAC 0x10 -+#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \ -+ | EBT_ENTRY_OR_ENTRIES) -+ -+#define EBT_IPROTO 0x01 -+#define EBT_IIN 0x02 -+#define EBT_IOUT 0x04 -+#define EBT_ISOURCE 0x8 -+#define EBT_IDEST 0x10 -+#define EBT_ILOGICALIN 0x20 -+#define EBT_ILOGICALOUT 0x40 -+#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \ -+ | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST) -+ -+struct ebt_entry_match -+{ -+ union { -+ char name[EBT_FUNCTION_MAXNAMELEN]; -+ struct ebt_match *match; -+ } u; -+ // size of data -+ unsigned int match_size; -+ unsigned char data[0]; -+}; -+ -+struct ebt_entry_watcher -+{ -+ union { -+ char name[EBT_FUNCTION_MAXNAMELEN]; -+ struct ebt_watcher *watcher; -+ } u; -+ // size of data -+ unsigned int watcher_size; -+ unsigned char data[0]; -+}; -+ -+struct ebt_entry_target -+{ -+ union { -+ char name[EBT_FUNCTION_MAXNAMELEN]; -+ struct ebt_target *target; -+ } u; -+ // size of data -+ unsigned int target_size; -+ unsigned char data[0]; -+}; -+ -+#define EBT_STANDARD_TARGET "standard" -+struct ebt_standard_target -+{ -+ struct ebt_entry_target target; -+ int verdict; -+}; -+ -+// one entry -+struct ebt_entry { -+ // this needs to be the first field -+ unsigned int bitmask; -+ unsigned int invflags; -+ uint16_t ethproto; -+ // the physical in-dev -+ char in[IFNAMSIZ]; -+ // the logical in-dev -+ char logical_in[IFNAMSIZ]; -+ // the physical out-dev -+ char out[IFNAMSIZ]; -+ // the logical out-dev -+ char logical_out[IFNAMSIZ]; -+ unsigned char sourcemac[ETH_ALEN]; -+ unsigned char sourcemsk[ETH_ALEN]; -+ unsigned char destmac[ETH_ALEN]; -+ unsigned char destmsk[ETH_ALEN]; -+ // sizeof ebt_entry + matches -+ unsigned int watchers_offset; -+ // sizeof ebt_entry + matches + watchers -+ unsigned int target_offset; -+ // sizeof ebt_entry + matches + watchers + target -+ unsigned int next_offset; -+ unsigned char elems[0]; -+}; -+ -+struct ebt_replace -+{ -+ char name[EBT_TABLE_MAXNAMELEN]; -+ unsigned int valid_hooks; -+ // nr of rules in the table -+ unsigned int nentries; -+ // total size of the entries -+ unsigned int entries_size; -+ // start of the chains -+ struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; -+ // nr of counters userspace expects back -+ unsigned int num_counters; -+ // where the kernel will put the old counters -+ struct ebt_counter *counters; -+ char *entries; -+}; -+ -+// [gs]etsockopt numbers -+#define EBT_BASE_CTL 128 -+ -+#define EBT_SO_SET_ENTRIES (EBT_BASE_CTL) -+#define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES+1) -+#define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS+1) -+ -+#define EBT_SO_GET_INFO (EBT_BASE_CTL) -+#define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1) -+#define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1) -+#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1) -+#define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1) -+ -+#ifdef __KERNEL__ -+ -+// return values for match() functions -+#define EBT_MATCH 0 -+#define EBT_NOMATCH 1 -+ -+struct ebt_match -+{ -+ struct list_head list; -+ const char name[EBT_FUNCTION_MAXNAMELEN]; -+ // 0 == it matches -+ int (*match)(const struct sk_buff *skb, const struct net_device *in, -+ const struct net_device *out, const void *matchdata, -+ unsigned int datalen); -+ // 0 == let it in -+ int (*check)(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *matchdata, unsigned int datalen); -+ void (*destroy)(void *matchdata, unsigned int datalen); -+ struct module *me; -+}; -+ -+struct ebt_watcher -+{ -+ struct list_head list; -+ const char name[EBT_FUNCTION_MAXNAMELEN]; -+ void (*watcher)(const struct sk_buff *skb, const struct net_device *in, -+ const struct net_device *out, const void *watcherdata, -+ unsigned int datalen); -+ // 0 == let it in -+ int (*check)(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *watcherdata, unsigned int datalen); -+ void (*destroy)(void *watcherdata, unsigned int datalen); -+ struct module *me; -+}; -+ -+struct ebt_target -+{ -+ struct list_head list; -+ const char name[EBT_FUNCTION_MAXNAMELEN]; -+ // returns one of the standard verdicts -+ int (*target)(struct sk_buff **pskb, unsigned int hooknr, -+ const struct net_device *in, const struct net_device *out, -+ const void *targetdata, unsigned int datalen); -+ // 0 == let it in -+ int (*check)(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *targetdata, unsigned int datalen); -+ void (*destroy)(void *targetdata, unsigned int datalen); -+ struct module *me; -+}; -+ -+// used for jumping from and into user defined chains (udc) -+struct ebt_chainstack -+{ -+ struct ebt_entries *chaininfo; // pointer to chain data -+ struct ebt_entry *e; // pointer to entry data -+ unsigned int n; // n'th entry -+}; -+ -+struct ebt_table_info -+{ -+ // total size of the entries -+ unsigned int entries_size; -+ unsigned int nentries; -+ // pointers to the start of the chains -+ struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; -+ // room to maintain the stack used for jumping from and into udc -+ struct ebt_chainstack **chainstack; -+ char *entries; -+ struct ebt_counter counters[0] ____cacheline_aligned; -+}; -+ -+struct ebt_table -+{ -+ struct list_head list; -+ char name[EBT_TABLE_MAXNAMELEN]; -+ struct ebt_replace *table; -+ unsigned int valid_hooks; -+ rwlock_t lock; -+ // e.g. could be the table explicitly only allows certain -+ // matches, targets, ... 0 == let it in -+ int (*check)(const struct ebt_table_info *info, -+ unsigned int valid_hooks); -+ // the data used by the kernel -+ struct ebt_table_info *private; -+}; -+ -+#define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_entry_target)-1)) & \ -+ ~(__alignof__(struct ebt_entry_target)-1)) -+extern int ebt_register_table(struct ebt_table *table); -+extern void ebt_unregister_table(struct ebt_table *table); -+extern int ebt_register_match(struct ebt_match *match); -+extern void ebt_unregister_match(struct ebt_match *match); -+extern int ebt_register_watcher(struct ebt_watcher *watcher); -+extern void ebt_unregister_watcher(struct ebt_watcher *watcher); -+extern int ebt_register_target(struct ebt_target *target); -+extern void ebt_unregister_target(struct ebt_target *target); -+extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff **pskb, -+ const struct net_device *in, const struct net_device *out, -+ struct ebt_table *table); -+ -+ // Used in the kernel match() functions -+#define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg)) -+// True if the hook mask denotes that the rule is in a base chain, -+// used in the check() functions -+#define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS)) -+// Clear the bit in the hook mask that tells if the rule is on a base chain -+#define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS)) -+// True if the target is not a standard target -+#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) -+ -+#endif /* __KERNEL__ */ -+ -+// blatently stolen from ip_tables.h -+// fn returns 0 to continue iteration -+#define EBT_MATCH_ITERATE(e, fn, args...) \ -+({ \ -+ unsigned int __i; \ -+ int __ret = 0; \ -+ struct ebt_entry_match *__match; \ -+ \ -+ for (__i = sizeof(struct ebt_entry); \ -+ __i < (e)->watchers_offset; \ -+ __i += __match->match_size + \ -+ sizeof(struct ebt_entry_match)) { \ -+ __match = (void *)(e) + __i; \ -+ \ -+ __ret = fn(__match , ## args); \ -+ if (__ret != 0) \ -+ break; \ -+ } \ -+ if (__ret == 0) { \ -+ if (__i != (e)->watchers_offset) \ -+ __ret = -EINVAL; \ -+ } \ -+ __ret; \ -+}) -+ -+#define EBT_WATCHER_ITERATE(e, fn, args...) \ -+({ \ -+ unsigned int __i; \ -+ int __ret = 0; \ -+ struct ebt_entry_watcher *__watcher; \ -+ \ -+ for (__i = e->watchers_offset; \ -+ __i < (e)->target_offset; \ -+ __i += __watcher->watcher_size + \ -+ sizeof(struct ebt_entry_watcher)) { \ -+ __watcher = (void *)(e) + __i; \ -+ \ -+ __ret = fn(__watcher , ## args); \ -+ if (__ret != 0) \ -+ break; \ -+ } \ -+ if (__ret == 0) { \ -+ if (__i != (e)->target_offset) \ -+ __ret = -EINVAL; \ -+ } \ -+ __ret; \ -+}) -+ -+#define EBT_ENTRY_ITERATE(entries, size, fn, args...) \ -+({ \ -+ unsigned int __i; \ -+ int __ret = 0; \ -+ struct ebt_entry *__entry; \ -+ \ -+ for (__i = 0; __i < (size);) { \ -+ __entry = (void *)(entries) + __i; \ -+ __ret = fn(__entry , ## args); \ -+ if (__ret != 0) \ -+ break; \ -+ if (__entry->bitmask != 0) \ -+ __i += __entry->next_offset; \ -+ else \ -+ __i += sizeof(struct ebt_entries); \ -+ } \ -+ if (__ret == 0) { \ -+ if (__i != (size)) \ -+ __ret = -EINVAL; \ -+ } \ -+ __ret; \ -+}) -+ -+#endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge.h src/linux/linux/include/linux/netfilter_bridge.h ---- src/linux/linux.stock/include/linux/netfilter_bridge.h 2003-07-04 04:12:26.000000000 -0400 -+++ src/linux/linux/include/linux/netfilter_bridge.h 2004-07-10 23:46:39.000000000 -0400 -@@ -6,6 +6,10 @@ - - #include - #include -+#if defined(__KERNEL__) && defined(CONFIG_NETFILTER) -+#include -+#include -+#endif - - /* Bridge Hooks */ - /* After promisc drops, checksum checks. */ -@@ -18,7 +22,76 @@ - #define NF_BR_LOCAL_OUT 3 - /* Packets about to hit the wire. */ - #define NF_BR_POST_ROUTING 4 --#define NF_BR_NUMHOOKS 5 -+/* Not really a hook, but used for the ebtables broute table */ -+#define NF_BR_BROUTING 5 -+#define NF_BR_NUMHOOKS 6 -+ -+#ifdef __KERNEL__ -+ -+#define BRNF_PKT_TYPE 0x01 -+#define BRNF_BRIDGED_DNAT 0x02 -+#define BRNF_DONT_TAKE_PARENT 0x04 -+#define BRNF_BRIDGED 0x08 -+#define BRNF_NF_BRIDGE_PREROUTING 0x10 -+ -+enum nf_br_hook_priorities { -+ NF_BR_PRI_FIRST = INT_MIN, -+ NF_BR_PRI_NAT_DST_BRIDGED = -300, -+ NF_BR_PRI_FILTER_BRIDGED = -200, -+ NF_BR_PRI_BRNF = 0, -+ NF_BR_PRI_NAT_DST_OTHER = 100, -+ NF_BR_PRI_FILTER_OTHER = 200, -+ NF_BR_PRI_NAT_SRC = 300, -+ NF_BR_PRI_LAST = INT_MAX, -+}; -+ -+#ifdef CONFIG_NETFILTER -+static inline -+struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) -+{ -+ struct nf_bridge_info **nf_bridge = &(skb->nf_bridge); -+ -+ if ((*nf_bridge = kmalloc(sizeof(**nf_bridge), GFP_ATOMIC)) != NULL) { -+ atomic_set(&(*nf_bridge)->use, 1); -+ (*nf_bridge)->mask = 0; -+ (*nf_bridge)->physindev = (*nf_bridge)->physoutdev = NULL; -+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -+ (*nf_bridge)->netoutdev = NULL; -+#endif -+ } -+ -+ return *nf_bridge; -+} -+ -+/* Only used in br_forward.c */ -+static inline -+void nf_bridge_maybe_copy_header(struct sk_buff *skb) -+{ -+ if (skb->nf_bridge) { -+ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { -+ memcpy(skb->data - 18, skb->nf_bridge->data, 18); -+ skb_push(skb, 4); -+ } else -+ memcpy(skb->data - 16, skb->nf_bridge->data, 16); -+ } -+} -+ -+static inline -+void nf_bridge_save_header(struct sk_buff *skb) -+{ -+ int header_size = 16; -+ -+ if (skb->protocol == __constant_htons(ETH_P_8021Q)) -+ header_size = 18; -+ memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); -+} - -+struct bridge_skb_cb { -+ union { -+ __u32 ipv4; -+ } daddr; -+}; -+#endif /* CONFIG_NETFILTER */ - -+#endif /* __KERNEL__ */ - #endif -diff -Nurb src/linux/linux.stock/include/linux/netfilter_ipv4/ipt_physdev.h src/linux/linux/include/linux/netfilter_ipv4/ipt_physdev.h ---- src/linux/linux.stock/include/linux/netfilter_ipv4/ipt_physdev.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/netfilter_ipv4/ipt_physdev.h 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,24 @@ -+#ifndef _IPT_PHYSDEV_H -+#define _IPT_PHYSDEV_H -+ -+#ifdef __KERNEL__ -+#include -+#endif -+ -+#define IPT_PHYSDEV_OP_IN 0x01 -+#define IPT_PHYSDEV_OP_OUT 0x02 -+#define IPT_PHYSDEV_OP_BRIDGED 0x04 -+#define IPT_PHYSDEV_OP_ISIN 0x08 -+#define IPT_PHYSDEV_OP_ISOUT 0x10 -+#define IPT_PHYSDEV_OP_MASK (0x20 - 1) -+ -+struct ipt_physdev_info { -+ char physindev[IFNAMSIZ]; -+ char in_mask[IFNAMSIZ]; -+ char physoutdev[IFNAMSIZ]; -+ char out_mask[IFNAMSIZ]; -+ u_int8_t invert; -+ u_int8_t bitmask; -+}; -+ -+#endif /*_IPT_PHYSDEV_H*/ -diff -Nurb src/linux/linux.stock/include/linux/netfilter_ipv4.h src/linux/linux/include/linux/netfilter_ipv4.h ---- src/linux/linux.stock/include/linux/netfilter_ipv4.h 2004-07-10 23:30:09.000000000 -0400 -+++ src/linux/linux/include/linux/netfilter_ipv4.h 2004-07-10 23:46:39.000000000 -0400 -@@ -54,8 +54,10 @@ - NF_IP_PRI_CONNTRACK_DEFRAG = -400, - NF_IP_PRI_RAW = -300, - NF_IP_PRI_CONNTRACK = -200, -+ NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175, - NF_IP_PRI_MANGLE = -150, - NF_IP_PRI_NAT_DST = -100, -+ NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50, - NF_IP_PRI_FILTER = 0, - NF_IP_PRI_NAT_SRC = 100, - NF_IP_PRI_LAST = INT_MAX, -diff -Nurb src/linux/linux.stock/include/linux/skbuff.h src/linux/linux/include/linux/skbuff.h ---- src/linux/linux.stock/include/linux/skbuff.h 2003-07-04 04:12:26.000000000 -0400 -+++ src/linux/linux/include/linux/skbuff.h 2004-07-10 23:46:39.000000000 -0400 -@@ -92,6 +92,20 @@ - struct nf_ct_info { - struct nf_conntrack *master; - }; -+ -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+struct nf_bridge_info { -+ atomic_t use; -+ struct net_device *physindev; -+ struct net_device *physoutdev; -+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -+ struct net_device *netoutdev; -+#endif -+ unsigned int mask; -+ unsigned long data[32 / sizeof(unsigned long)]; -+}; -+#endif -+ - #endif - - struct sk_buff_head { -@@ -204,6 +218,9 @@ - #ifdef CONFIG_NETFILTER_DEBUG - unsigned int nf_debug; - #endif -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ struct nf_bridge_info *nf_bridge; /* Saved data about a bridged frame - see br_netfilter.c */ -+#endif - #endif /*CONFIG_NETFILTER*/ - - #if defined(CONFIG_HIPPI) -@@ -1143,6 +1160,20 @@ - if (nfct) - atomic_inc(&nfct->master->use); - } -+ -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge) -+{ -+ if (nf_bridge && atomic_dec_and_test(&nf_bridge->use)) -+ kfree(nf_bridge); -+} -+static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge) -+{ -+ if (nf_bridge) -+ atomic_inc(&nf_bridge->use); -+} -+#endif -+ - #endif - - #endif /* __KERNEL__ */ -diff -Nurb src/linux/linux.stock/include/linux/sysctl.h src/linux/linux/include/linux/sysctl.h ---- src/linux/linux.stock/include/linux/sysctl.h 2004-07-10 23:29:55.000000000 -0400 -+++ src/linux/linux/include/linux/sysctl.h 2004-07-10 23:46:39.000000000 -0400 -@@ -547,6 +547,15 @@ - NET_DECNET_CONF_DEV_STATE = 7 - }; - -+/* /proc/sys/net/bridge */ -+enum { -+ NET_BRIDGE_NF_CALL_ARPTABLES = 1, -+ NET_BRIDGE_NF_CALL_IPTABLES = 2, -+ NET_BRIDGE_NF_CALL_IP6TABLES = 3, -+ NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4, -+}; -+ -+ - /* CTL_PROC names: */ - - /* CTL_FS names: */ -diff -Nurb src/linux/linux.stock/net/8021q/vlan_dev.c src/linux/linux/net/8021q/vlan_dev.c ---- src/linux/linux.stock/net/8021q/vlan_dev.c 2003-07-04 04:12:29.000000000 -0400 -+++ src/linux/linux/net/8021q/vlan_dev.c 2004-07-10 23:46:39.000000000 -0400 -@@ -503,6 +503,10 @@ - stats->tx_packets++; /* for statics only */ - stats->tx_bytes += skb->len; - -+ skb->protocol = __constant_htons(ETH_P_8021Q); -+ skb->mac.raw -= VLAN_HLEN; -+ skb->nh.raw -= VLAN_HLEN; -+ - dev_queue_xmit(skb); - - return 0; -diff -Nurb src/linux/linux.stock/net/Config.in src/linux/linux/net/Config.in ---- src/linux/linux.stock/net/Config.in 2004-07-10 23:29:49.000000000 -0400 -+++ src/linux/linux/net/Config.in 2004-07-10 23:46:39.000000000 -0400 -@@ -68,6 +68,9 @@ - source net/decnet/Config.in - fi - dep_tristate '802.1d Ethernet Bridging' CONFIG_BRIDGE $CONFIG_INET -+if [ "$CONFIG_BRIDGE" != "n" -a "$CONFIG_NETFILTER" != "n" ]; then -+ source net/bridge/netfilter/Config.in -+fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25 - tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB -diff -Nurb src/linux/linux.stock/net/Makefile src/linux/linux/net/Makefile ---- src/linux/linux.stock/net/Makefile 2004-07-10 23:29:49.000000000 -0400 -+++ src/linux/linux/net/Makefile 2004-07-10 23:49:10.000000000 -0400 -@@ -26,6 +26,12 @@ - endif - endif - -+ifneq ($(CONFIG_BRIDGE),n) -+ifneq ($(CONFIG_BRIDGE),) -+subdir-$(CONFIG_BRIDGE) += bridge/netfilter -+endif -+endif -+ - subdir-$(CONFIG_KHTTPD) += khttpd - subdir-$(CONFIG_PACKET) += packet - subdir-$(CONFIG_NET_SCHED) += sched -diff -Nurb src/linux/linux.stock/net/bridge/Makefile src/linux/linux/net/bridge/Makefile ---- src/linux/linux.stock/net/bridge/Makefile 2003-07-04 04:12:30.000000000 -0400 -+++ src/linux/linux/net/bridge/Makefile 2004-07-10 23:46:39.000000000 -0400 -@@ -7,10 +7,17 @@ - # - # Note 2! The CFLAGS definition is now in the main makefile... - -+export-objs := br.o -+ - O_TARGET := bridge.o - obj-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \ - br_ioctl.o br_notify.o br_stp.o br_stp_bpdu.o \ - br_stp_if.o br_stp_timer.o -+ -+ifeq ($(CONFIG_NETFILTER),y) -+obj-y += br_netfilter.o -+endif -+ - obj-m := $(O_TARGET) - - include $(TOPDIR)/Rules.make -diff -Nurb src/linux/linux.stock/net/bridge/br.c src/linux/linux/net/bridge/br.c ---- src/linux/linux.stock/net/bridge/br.c 2003-10-14 04:09:32.000000000 -0400 -+++ src/linux/linux/net/bridge/br.c 2004-07-10 23:46:39.000000000 -0400 -@@ -29,6 +29,8 @@ - #include "../atm/lec.h" - #endif - -+int (*br_should_route_hook) (struct sk_buff **pskb) = NULL; -+ - void br_dec_use_count() - { - MOD_DEC_USE_COUNT; -@@ -43,6 +45,10 @@ - { - printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n"); - -+#ifdef CONFIG_NETFILTER -+ if (br_netfilter_init()) -+ return 1; -+#endif - br_handle_frame_hook = br_handle_frame; - br_ioctl_hook = br_ioctl_deviceless_stub; - #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) -@@ -61,6 +67,9 @@ - - static void __exit br_deinit(void) - { -+#ifdef CONFIG_NETFILTER -+ br_netfilter_fini(); -+#endif - unregister_netdevice_notifier(&br_device_notifier); - br_call_ioctl_atomic(__br_clear_ioctl_hook); - -@@ -74,7 +83,7 @@ - #endif - } - --EXPORT_NO_SYMBOLS; -+EXPORT_SYMBOL(br_should_route_hook); - - module_init(br_init) - module_exit(br_deinit) -diff -Nurb src/linux/linux.stock/net/bridge/br_forward.c src/linux/linux/net/bridge/br_forward.c ---- src/linux/linux.stock/net/bridge/br_forward.c 2003-10-14 04:09:32.000000000 -0400 -+++ src/linux/linux/net/bridge/br_forward.c 2004-07-10 23:46:39.000000000 -0400 -@@ -30,18 +30,21 @@ - return 1; - } - --static int __dev_queue_push_xmit(struct sk_buff *skb) -+int br_dev_queue_push_xmit(struct sk_buff *skb) - { -+#ifdef CONFIG_NETFILTER -+ nf_bridge_maybe_copy_header(skb); -+#endif - skb_push(skb, ETH_HLEN); - dev_queue_xmit(skb); - - return 0; - } - --static int __br_forward_finish(struct sk_buff *skb) -+int br_forward_finish(struct sk_buff *skb) - { - NF_HOOK(PF_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev, -- __dev_queue_push_xmit); -+ br_dev_queue_push_xmit); - - return 0; - } -@@ -49,8 +52,11 @@ - static void __br_deliver(struct net_bridge_port *to, struct sk_buff *skb) - { - skb->dev = to->dev; -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug = 0; -+#endif - NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, -- __br_forward_finish); -+ br_forward_finish); - } - - static void __br_forward(struct net_bridge_port *to, struct sk_buff *skb) -@@ -61,7 +67,7 @@ - skb->dev = to->dev; - - NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev, -- __br_forward_finish); -+ br_forward_finish); - } - - /* called under bridge lock */ -diff -Nurb src/linux/linux.stock/net/bridge/br_input.c src/linux/linux/net/bridge/br_input.c ---- src/linux/linux.stock/net/bridge/br_input.c 2003-10-14 04:09:32.000000000 -0400 -+++ src/linux/linux/net/bridge/br_input.c 2004-07-10 23:48:36.000000000 -0400 -@@ -24,6 +24,9 @@ - - static int br_pass_frame_up_finish(struct sk_buff *skb) - { -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug = 0; -+#endif - netif_rx(skb); - - return 0; -@@ -46,7 +49,7 @@ - br_pass_frame_up_finish); - } - --static int br_handle_frame_finish(struct sk_buff *skb) -+int br_handle_frame_finish(struct sk_buff *skb) - { - struct net_bridge *br; - unsigned char *dest; -@@ -112,7 +115,7 @@ - return 0; - } - --void br_handle_frame(struct sk_buff *skb) -+int br_handle_frame(struct sk_buff *skb) - { - struct net_bridge *br; - unsigned char *dest; -@@ -146,25 +149,34 @@ - goto handle_special_frame; - - if (p->state == BR_STATE_FORWARDING) { -+ if (br_should_route_hook && br_should_route_hook(&skb)) { -+ read_unlock(&br->lock); -+ return -1; -+ } -+ -+ if (!memcmp(p->br->dev.dev_addr, dest, ETH_ALEN)) -+ skb->pkt_type = PACKET_HOST; -+ - NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, - br_handle_frame_finish); - read_unlock(&br->lock); -- return; -+ return 0; - } - - err: - read_unlock(&br->lock); - err_nolock: - kfree_skb(skb); -- return; -+ return 0; - - handle_special_frame: - if (!dest[5]) { - br_stp_handle_bpdu(skb); - read_unlock(&br->lock); -- return; -+ return 0; - } - - read_unlock(&br->lock); - kfree_skb(skb); -+ return 0; - } -diff -Nurb src/linux/linux.stock/net/bridge/br_netfilter.c src/linux/linux/net/bridge/br_netfilter.c ---- src/linux/linux.stock/net/bridge/br_netfilter.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/br_netfilter.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,896 @@ -+/* -+ * Handle firewalling -+ * Linux ethernet bridge -+ * -+ * Authors: -+ * Lennert Buytenhek -+ * Bart De Schuymer (maintainer) -+ * -+ * Changes: -+ * Apr 29 2003: physdev module support (bdschuym) -+ * Jun 19 2003: let arptables see bridged ARP traffic (bdschuym) -+ * Oct 06 2003: filter encapsulated IP/ARP VLAN traffic on untagged bridge -+ * (bdschuym) -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Lennert dedicates this file to Kerstin Wurdinger. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "br_private.h" -+#ifdef CONFIG_SYSCTL -+#include -+#endif -+ -+ -+#define skb_origaddr(skb) (((struct bridge_skb_cb *) \ -+ (skb->nf_bridge->data))->daddr.ipv4) -+#define store_orig_dstaddr(skb) (skb_origaddr(skb) = (skb)->nh.iph->daddr) -+#define dnat_took_place(skb) (skb_origaddr(skb) != (skb)->nh.iph->daddr) -+ -+#define has_bridge_parent(device) ((device)->br_port != NULL) -+#define bridge_parent(device) (&((device)->br_port->br->dev)) -+ -+#ifdef CONFIG_SYSCTL -+static struct ctl_table_header *brnf_sysctl_header; -+static int brnf_call_iptables = 1; -+static int brnf_call_arptables = 1; -+static int brnf_filter_vlan_tagged = 1; -+#else -+#define brnf_filter_vlan_tagged 1 -+#endif -+ -+#define IS_VLAN_IP (skb->protocol == __constant_htons(ETH_P_8021Q) && \ -+ hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP) && \ -+ brnf_filter_vlan_tagged) -+/* -+#define IS_VLAN_ARP (skb->protocol == __constant_htons(ETH_P_8021Q) && \ -+ hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_ARP) && \ -+ brnf_filter_vlan_tagged) -+*/ -+ -+/* We need these fake structures to make netfilter happy -- -+ * lots of places assume that skb->dst != NULL, which isn't -+ * all that unreasonable. -+ * -+ * Currently, we fill in the PMTU entry because netfilter -+ * refragmentation needs it, and the rt_flags entry because -+ * ipt_REJECT needs it. Future netfilter modules might -+ * require us to fill additional fields. -+ */ -+static struct net_device __fake_net_device = { -+ .hard_header_len = ETH_HLEN -+}; -+ -+static struct rtable __fake_rtable = { -+ u: { -+ dst: { -+ __refcnt: ATOMIC_INIT(1), -+ dev: &__fake_net_device, -+ pmtu: 1500 -+ } -+ }, -+ -+ rt_flags: 0 -+}; -+ -+ -+/* PF_BRIDGE/PRE_ROUTING *********************************************/ -+static void __br_dnat_complain(void) -+{ -+ static unsigned long last_complaint; -+ -+ if (jiffies - last_complaint >= 5 * HZ) { -+ printk(KERN_WARNING "Performing cross-bridge DNAT requires IP " -+ "forwarding to be enabled\n"); -+ last_complaint = jiffies; -+ } -+} -+ -+ -+/* This requires some explaining. If DNAT has taken place, -+ * we will need to fix up the destination Ethernet address, -+ * and this is a tricky process. -+ * -+ * There are two cases to consider: -+ * 1. The packet was DNAT'ed to a device in the same bridge -+ * port group as it was received on. We can still bridge -+ * the packet. -+ * 2. The packet was DNAT'ed to a different device, either -+ * a non-bridged device or another bridge port group. -+ * The packet will need to be routed. -+ * -+ * The correct way of distinguishing between these two cases is to -+ * call ip_route_input() and to look at skb->dst->dev, which is -+ * changed to the destination device if ip_route_input() succeeds. -+ * -+ * Let us first consider the case that ip_route_input() succeeds: -+ * -+ * If skb->dst->dev equals the logical bridge device the packet -+ * came in on, we can consider this bridging. We then call -+ * skb->dst->output() which will make the packet enter br_nf_local_out() -+ * not much later. In that function it is assured that the iptables -+ * FORWARD chain is traversed for the packet. -+ * -+ * Otherwise, the packet is considered to be routed and we just -+ * change the destination MAC address so that the packet will -+ * later be passed up to the IP stack to be routed. -+ * -+ * Let us now consider the case that ip_route_input() fails: -+ * -+ * After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input() -+ * will fail, while __ip_route_output_key() will return success. The source -+ * address for __ip_route_output_key() is set to zero, so __ip_route_output_key -+ * thinks we're handling a locally generated packet and won't care -+ * if IP forwarding is allowed. We send a warning message to the users's -+ * log telling her to put IP forwarding on. -+ * -+ * ip_route_input() will also fail if there is no route available. -+ * In that case we just drop the packet. -+ * -+ * --Lennert, 20020411 -+ * --Bart, 20020416 (updated) -+ * --Bart, 20021007 (updated) -+ */ -+ -+static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) -+{ -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug |= (1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_FORWARD); -+#endif -+ -+ if (skb->pkt_type == PACKET_OTHERHOST) { -+ skb->pkt_type = PACKET_HOST; -+ skb->nf_bridge->mask |= BRNF_PKT_TYPE; -+ } -+ skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; -+ -+ skb->dev = bridge_parent(skb->dev); -+ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { -+ skb_pull(skb, VLAN_HLEN); -+ skb->nh.raw += VLAN_HLEN; -+ } -+ skb->dst->output(skb); -+ return 0; -+} -+ -+static int br_nf_pre_routing_finish(struct sk_buff *skb) -+{ -+ struct net_device *dev = skb->dev; -+ struct iphdr *iph = skb->nh.iph; -+ struct nf_bridge_info *nf_bridge = skb->nf_bridge; -+ -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING); -+#endif -+ -+ if (nf_bridge->mask & BRNF_PKT_TYPE) { -+ skb->pkt_type = PACKET_OTHERHOST; -+ nf_bridge->mask ^= BRNF_PKT_TYPE; -+ } -+ nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; -+ -+ if (dnat_took_place(skb)) { -+ if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, -+ dev)) { -+ struct rtable *rt; -+ -+ if (!ip_route_output(&rt, iph->daddr, 0, iph->tos, 0)) { -+ /* Bridged-and-DNAT'ed traffic doesn't -+ * require ip_forwarding. -+ */ -+ if (((struct dst_entry *)rt)->dev == dev) { -+ skb->dst = (struct dst_entry *)rt; -+ goto bridged_dnat; -+ } -+ __br_dnat_complain(); -+ dst_release((struct dst_entry *)rt); -+ } -+ kfree_skb(skb); -+ return 0; -+ } else { -+ if (skb->dst->dev == dev) { -+bridged_dnat: -+ /* Tell br_nf_local_out this is a -+ * bridged frame -+ */ -+ nf_bridge->mask |= BRNF_BRIDGED_DNAT; -+ skb->dev = nf_bridge->physindev; -+ if (skb->protocol == -+ __constant_htons(ETH_P_8021Q)) { -+ skb_push(skb, VLAN_HLEN); -+ skb->nh.raw -= VLAN_HLEN; -+ } -+ NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, -+ skb, skb->dev, NULL, -+ br_nf_pre_routing_finish_bridge, -+ 1); -+ return 0; -+ } -+ memcpy(skb->mac.ethernet->h_dest, dev->dev_addr, -+ ETH_ALEN); -+ skb->pkt_type = PACKET_HOST; -+ } -+ } else { -+ skb->dst = (struct dst_entry *)&__fake_rtable; -+ dst_hold(skb->dst); -+ } -+ -+ skb->dev = nf_bridge->physindev; -+ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { -+ skb_push(skb, VLAN_HLEN); -+ skb->nh.raw -= VLAN_HLEN; -+ } -+ NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, -+ br_handle_frame_finish, 1); -+ -+ return 0; -+} -+ -+/* Replicate the checks that IPv4 does on packet reception. -+ * Set skb->dev to the bridge device (i.e. parent of the -+ * receiving device) to make netfilter happy, the REDIRECT -+ * target in particular. Save the original destination IP -+ * address to be able to detect DNAT afterwards. -+ */ -+static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, -+ const struct net_device *in, const struct net_device *out, -+ int (*okfn)(struct sk_buff *)) -+{ -+ struct iphdr *iph; -+ __u32 len; -+ struct sk_buff *skb = *pskb; -+ struct nf_bridge_info *nf_bridge; -+ -+#ifdef CONFIG_SYSCTL -+ if (!brnf_call_iptables) -+ return NF_ACCEPT; -+#endif -+ -+ if (skb->protocol != __constant_htons(ETH_P_IP)) { -+ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *) -+ ((*pskb)->mac.ethernet); -+ -+ if (!IS_VLAN_IP) -+ return NF_ACCEPT; -+ if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) -+ goto out; -+ skb_pull(*pskb, VLAN_HLEN); -+ (*pskb)->nh.raw += VLAN_HLEN; -+ } else if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) -+ goto out; -+ -+ if (!pskb_may_pull(skb, sizeof(struct iphdr))) -+ goto inhdr_error; -+ -+ iph = skb->nh.iph; -+ if (iph->ihl < 5 || iph->version != 4) -+ goto inhdr_error; -+ -+ if (!pskb_may_pull(skb, 4*iph->ihl)) -+ goto inhdr_error; -+ -+ iph = skb->nh.iph; -+ if (ip_fast_csum((__u8 *)iph, iph->ihl) != 0) -+ goto inhdr_error; -+ -+ len = ntohs(iph->tot_len); -+ if (skb->len < len || len < 4*iph->ihl) -+ goto inhdr_error; -+ -+ if (skb->len > len) { -+ __pskb_trim(skb, len); -+ if (skb->ip_summed == CHECKSUM_HW) -+ skb->ip_summed = CHECKSUM_NONE; -+ } -+ -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug ^= (1 << NF_IP_PRE_ROUTING); -+#endif -+ if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) -+ return NF_DROP; -+ -+ if (skb->pkt_type == PACKET_OTHERHOST) { -+ skb->pkt_type = PACKET_HOST; -+ nf_bridge->mask |= BRNF_PKT_TYPE; -+ } -+ -+ nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING; -+ nf_bridge->physindev = skb->dev; -+ skb->dev = bridge_parent(skb->dev); -+ store_orig_dstaddr(skb); -+ -+ NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, -+ br_nf_pre_routing_finish); -+ -+ return NF_STOLEN; -+ -+inhdr_error: -+// IP_INC_STATS_BH(IpInHdrErrors); -+out: -+ return NF_DROP; -+} -+ -+ -+/* PF_BRIDGE/LOCAL_IN ************************************************/ -+/* The packet is locally destined, which requires a real -+ * dst_entry, so detach the fake one. On the way up, the -+ * packet would pass through PRE_ROUTING again (which already -+ * took place when the packet entered the bridge), but we -+ * register an IPv4 PRE_ROUTING 'sabotage' hook that will -+ * prevent this from happening. -+ */ -+static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb, -+ const struct net_device *in, const struct net_device *out, -+ int (*okfn)(struct sk_buff *)) -+{ -+ struct sk_buff *skb = *pskb; -+ -+ if (skb->dst == (struct dst_entry *)&__fake_rtable) { -+ dst_release(skb->dst); -+ skb->dst = NULL; -+ } -+ -+ return NF_ACCEPT; -+} -+ -+/* PF_BRIDGE/FORWARD *************************************************/ -+static int br_nf_forward_finish(struct sk_buff *skb) -+{ -+ struct nf_bridge_info *nf_bridge = skb->nf_bridge; -+ struct net_device *in; -+ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); -+ -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug ^= (1 << NF_BR_FORWARD); -+#endif -+ -+ if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP) { -+ in = nf_bridge->physindev; -+ if (nf_bridge->mask & BRNF_PKT_TYPE) { -+ skb->pkt_type = PACKET_OTHERHOST; -+ nf_bridge->mask ^= BRNF_PKT_TYPE; -+ } -+ } else { -+ in = *((struct net_device **)(skb->cb)); -+ } -+ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { -+ skb_push(skb, VLAN_HLEN); -+ skb->nh.raw -= VLAN_HLEN; -+ } -+ NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in, -+ skb->dev, br_forward_finish, 1); -+ return 0; -+} -+ -+/* This is the 'purely bridged' case. For IP, we pass the packet to -+ * netfilter with indev and outdev set to the bridge device, -+ * but we are still able to filter on the 'real' indev/outdev -+ * because of the ipt_physdev.c module. For ARP, indev and outdev are the -+ * bridge ports. -+ */ -+static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb, -+ const struct net_device *in, const struct net_device *out, -+ int (*okfn)(struct sk_buff *)) -+{ -+ struct sk_buff *skb = *pskb; -+ struct nf_bridge_info *nf_bridge; -+ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); -+ -+#ifdef CONFIG_SYSCTL -+ if (!skb->nf_bridge) -+ return NF_ACCEPT; -+#endif -+ -+ if (skb->protocol != __constant_htons(ETH_P_IP)) { -+ if (!IS_VLAN_IP) -+ return NF_ACCEPT; -+ skb_pull(*pskb, VLAN_HLEN); -+ (*pskb)->nh.raw += VLAN_HLEN; -+ } -+ -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug ^= (1 << NF_BR_FORWARD); -+#endif -+ nf_bridge = skb->nf_bridge; -+ if (skb->pkt_type == PACKET_OTHERHOST) { -+ skb->pkt_type = PACKET_HOST; -+ nf_bridge->mask |= BRNF_PKT_TYPE; -+ } -+ -+ /* The physdev module checks on this */ -+ nf_bridge->mask |= BRNF_BRIDGED; -+ nf_bridge->physoutdev = skb->dev; -+ -+ NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(in), -+ bridge_parent(out), br_nf_forward_finish); -+ -+ return NF_STOLEN; -+} -+ -+/* -+static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, -+ const struct net_device *in, const struct net_device *out, -+ int (*okfn)(struct sk_buff *)) -+{ -+ struct sk_buff *skb = *pskb; -+ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); -+ struct net_device **d = (struct net_device **)(skb->cb); -+ -+ if (!brnf_call_arptables) -+ return NF_ACCEPT; -+ -+ if (skb->protocol != __constant_htons(ETH_P_ARP)) { -+ if (!IS_VLAN_ARP) -+ return NF_ACCEPT; -+ skb_pull(*pskb, VLAN_HLEN); -+ (*pskb)->nh.raw += VLAN_HLEN; -+ } -+ -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug ^= (1 << NF_BR_FORWARD); -+#endif -+ -+ if (skb->nh.arph->ar_pln != 4) { -+ if (IS_VLAN_ARP) { -+ skb_push(*pskb, VLAN_HLEN); -+ (*pskb)->nh.raw -= VLAN_HLEN; -+ } -+ return NF_ACCEPT; -+ } -+ *d = (struct net_device *)in; -+ NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in, -+ (struct net_device *)out, br_nf_forward_finish); -+ -+ return NF_STOLEN; -+} -+*/ -+ -+/* PF_BRIDGE/LOCAL_OUT ***********************************************/ -+static int br_nf_local_out_finish(struct sk_buff *skb) -+{ -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug &= ~(1 << NF_BR_LOCAL_OUT); -+#endif -+ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { -+ skb_push(skb, VLAN_HLEN); -+ skb->nh.raw -= VLAN_HLEN; -+ } -+ -+ NF_HOOK_THRESH(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, -+ br_forward_finish, NF_BR_PRI_FIRST + 1); -+ -+ return 0; -+} -+ -+ -+/* This function sees both locally originated IP packets and forwarded -+ * IP packets (in both cases the destination device is a bridge -+ * device). It also sees bridged-and-DNAT'ed packets. -+ * To be able to filter on the physical bridge devices (with the ipt_physdev.c -+ * module), we steal packets destined to a bridge device away from the -+ * PF_INET/FORWARD and PF_INET/OUTPUT hook functions, and give them back later, -+ * when we have determined the real output device. This is done in here. -+ * -+ * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged -+ * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward() -+ * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority -+ * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor -+ * will be executed. -+ * Otherwise, if nf_bridge->physindev is NULL, the bridge-nf code never touched -+ * this packet before, and so the packet was locally originated. We fake -+ * the PF_INET/LOCAL_OUT hook. -+ * Finally, if nf_bridge->physindev isn't NULL, then the packet was IP routed, -+ * so we fake the PF_INET/FORWARD hook. ipv4_sabotage_out() makes sure -+ * even routed packets that didn't arrive on a bridge interface have their -+ * nf_bridge->physindev set. -+ */ -+ -+static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, -+ const struct net_device *in, const struct net_device *out, -+ int (*_okfn)(struct sk_buff *)) -+{ -+ int (*okfn)(struct sk_buff *skb); -+ struct net_device *realindev; -+ struct sk_buff *skb = *pskb; -+ struct nf_bridge_info *nf_bridge; -+ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); -+ -+#ifdef CONFIG_SYSCTL -+ if (!skb->nf_bridge) -+ return NF_ACCEPT; -+#endif -+ -+ if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP) -+ return NF_ACCEPT; -+ -+ /* Sometimes we get packets with NULL ->dst here (for example, -+ * running a dhcp client daemon triggers this). -+ */ -+ if (skb->dst == NULL) -+ return NF_ACCEPT; -+ -+ nf_bridge = skb->nf_bridge; -+ nf_bridge->physoutdev = skb->dev; -+ realindev = nf_bridge->physindev; -+ -+ /* Bridged, take PF_BRIDGE/FORWARD. -+ * (see big note in front of br_nf_pre_routing_finish) -+ */ -+ if (nf_bridge->mask & BRNF_BRIDGED_DNAT) { -+ okfn = br_forward_finish; -+ -+ if (nf_bridge->mask & BRNF_PKT_TYPE) { -+ skb->pkt_type = PACKET_OTHERHOST; -+ nf_bridge->mask ^= BRNF_PKT_TYPE; -+ } -+ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { -+ skb_push(skb, VLAN_HLEN); -+ skb->nh.raw -= VLAN_HLEN; -+ } -+ -+ NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, -+ skb->dev, okfn); -+ } else { -+ struct net_device *realoutdev = bridge_parent(skb->dev); -+ -+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -+ /* iptables should match -o br0.x */ -+ if (nf_bridge->netoutdev) -+ realoutdev = nf_bridge->netoutdev; -+#endif -+ okfn = br_nf_local_out_finish; -+ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { -+ skb_pull(skb, VLAN_HLEN); -+ (*pskb)->nh.raw += VLAN_HLEN; -+ } -+ /* IP forwarded traffic has a physindev, locally -+ * generated traffic hasn't. -+ */ -+ if (realindev != NULL) { -+ if (((nf_bridge->mask & BRNF_DONT_TAKE_PARENT) == 0) && -+ has_bridge_parent(realindev)) -+ realindev = bridge_parent(realindev); -+ NF_HOOK_THRESH(PF_INET, NF_IP_FORWARD, skb, realindev, -+ realoutdev, okfn, -+ NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1); -+ } else { -+#ifdef CONFIG_NETFILTER_DEBUG -+ skb->nf_debug ^= (1 << NF_IP_LOCAL_OUT); -+#endif -+ -+ NF_HOOK_THRESH(PF_INET, NF_IP_LOCAL_OUT, skb, realindev, -+ realoutdev, okfn, -+ NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1); -+ } -+ } -+ -+ return NF_STOLEN; -+} -+ -+ -+/* PF_BRIDGE/POST_ROUTING ********************************************/ -+static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, -+ const struct net_device *in, const struct net_device *out, -+ int (*okfn)(struct sk_buff *)) -+{ -+ struct sk_buff *skb = *pskb; -+ struct nf_bridge_info *nf_bridge = (*pskb)->nf_bridge; -+ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); -+ struct net_device *realoutdev = bridge_parent(skb->dev); -+ -+#ifdef CONFIG_NETFILTER_DEBUG -+ /* Be very paranoid. This probably won't happen anymore, but let's -+ * keep the check just to be sure... */ -+ if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) { -+ printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: " -+ "bad mac.raw pointer."); -+ goto print_error; -+ } -+#endif -+ -+#ifdef CONFIG_SYSCTL -+ if (!nf_bridge) -+ return NF_ACCEPT; -+#endif -+ -+ if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP) -+ return NF_ACCEPT; -+ -+ /* Sometimes we get packets with NULL ->dst here (for example, -+ * running a dhcp client daemon triggers this). -+ */ -+ if (skb->dst == NULL) -+ return NF_ACCEPT; -+ -+#ifdef CONFIG_NETFILTER_DEBUG -+ /* Sometimes we get packets with NULL ->dst here (for example, -+ * running a dhcp client daemon triggers this). This should now -+ * be fixed, but let's keep the check around. -+ */ -+ if (skb->dst == NULL) { -+ printk(KERN_CRIT "br_netfilter: skb->dst == NULL."); -+ goto print_error; -+ } -+ -+ skb->nf_debug ^= (1 << NF_IP_POST_ROUTING); -+#endif -+ -+ /* We assume any code from br_dev_queue_push_xmit onwards doesn't care -+ * about the value of skb->pkt_type. -+ */ -+ if (skb->pkt_type == PACKET_OTHERHOST) { -+ skb->pkt_type = PACKET_HOST; -+ nf_bridge->mask |= BRNF_PKT_TYPE; -+ } -+ -+ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { -+ skb_pull(skb, VLAN_HLEN); -+ skb->nh.raw += VLAN_HLEN; -+ } -+ -+ nf_bridge_save_header(skb); -+ -+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -+ if (nf_bridge->netoutdev) -+ realoutdev = nf_bridge->netoutdev; -+#endif -+ NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, -+ realoutdev, br_dev_queue_push_xmit); -+ -+ return NF_STOLEN; -+ -+#ifdef CONFIG_NETFILTER_DEBUG -+print_error: -+ if (skb->dev != NULL) { -+ printk("[%s]", skb->dev->name); -+ if (has_bridge_parent(skb->dev)) -+ printk("[%s]", bridge_parent(skb->dev)->name); -+ } -+ printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw, -+ skb->data); -+ return NF_ACCEPT; -+#endif -+} -+ -+ -+/* IPv4/SABOTAGE *****************************************************/ -+ -+/* Don't hand locally destined packets to PF_INET/PRE_ROUTING -+ * for the second time. -+ */ -+static unsigned int ipv4_sabotage_in(unsigned int hook, struct sk_buff **pskb, -+ const struct net_device *in, const struct net_device *out, -+ int (*okfn)(struct sk_buff *)) -+{ -+ if ((*pskb)->nf_bridge && -+ !((*pskb)->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) { -+ okfn(*pskb); -+ return NF_STOLEN; -+ } -+ -+ return NF_ACCEPT; -+} -+ -+/* Postpone execution of PF_INET/FORWARD, PF_INET/LOCAL_OUT -+ * and PF_INET/POST_ROUTING until we have done the forwarding -+ * decision in the bridge code and have determined skb->physoutdev. -+ */ -+static unsigned int ipv4_sabotage_out(unsigned int hook, struct sk_buff **pskb, -+ const struct net_device *in, const struct net_device *out, -+ int (*okfn)(struct sk_buff *)) -+{ -+ struct sk_buff *skb = *pskb; -+ -+#ifdef CONFIG_SYSCTL -+ if (!brnf_call_iptables && !skb->nf_bridge) -+ return NF_ACCEPT; -+#endif -+ -+ if ((out->hard_start_xmit == br_dev_xmit && -+ okfn != br_nf_forward_finish && -+ okfn != br_nf_local_out_finish && -+ okfn != br_dev_queue_push_xmit) -+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -+ || ((out->priv_flags & IFF_802_1Q_VLAN) && -+ VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) -+#endif -+ ) { -+ struct nf_bridge_info *nf_bridge; -+ -+ if (!skb->nf_bridge && !nf_bridge_alloc(skb)) -+ return NF_DROP; -+ -+ nf_bridge = skb->nf_bridge; -+ -+ /* This frame will arrive on PF_BRIDGE/LOCAL_OUT and we -+ * will need the indev then. For a brouter, the real indev -+ * can be a bridge port, so we make sure br_nf_local_out() -+ * doesn't use the bridge parent of the indev by using -+ * the BRNF_DONT_TAKE_PARENT mask. -+ */ -+ if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { -+ nf_bridge->mask &= BRNF_DONT_TAKE_PARENT; -+ nf_bridge->physindev = (struct net_device *)in; -+ } -+#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) -+ /* the iptables outdev is br0.x, not br0 */ -+ if (out->priv_flags & IFF_802_1Q_VLAN) -+ nf_bridge->netoutdev = (struct net_device *)out; -+#endif -+ okfn(skb); -+ return NF_STOLEN; -+ } -+ -+ return NF_ACCEPT; -+} -+ -+/* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent -+ * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input. -+ * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because -+ * ip_refrag() can return NF_STOLEN. -+ */ -+static struct nf_hook_ops br_nf_ops[] = { -+ { .hook = br_nf_pre_routing, -+ .pf = PF_BRIDGE, -+ .hooknum = NF_BR_PRE_ROUTING, -+ .priority = NF_BR_PRI_BRNF, }, -+ { .hook = br_nf_local_in, -+ .pf = PF_BRIDGE, -+ .hooknum = NF_BR_LOCAL_IN, -+ .priority = NF_BR_PRI_BRNF, }, -+ { .hook = br_nf_forward_ip, -+ .pf = PF_BRIDGE, -+ .hooknum = NF_BR_FORWARD, -+ .priority = NF_BR_PRI_BRNF /*- 1*/, }, -+/* { .hook = br_nf_forward_arp, -+ .pf = PF_BRIDGE, -+ .hooknum = NF_BR_FORWARD, -+ .priority = NF_BR_PRI_BRNF, },*/ -+ { .hook = br_nf_local_out, -+ .pf = PF_BRIDGE, -+ .hooknum = NF_BR_LOCAL_OUT, -+ .priority = NF_BR_PRI_FIRST, }, -+ { .hook = br_nf_post_routing, -+ .pf = PF_BRIDGE, -+ .hooknum = NF_BR_POST_ROUTING, -+ .priority = NF_BR_PRI_LAST, }, -+ { .hook = ipv4_sabotage_in, -+ .pf = PF_INET, -+ .hooknum = NF_IP_PRE_ROUTING, -+ .priority = NF_IP_PRI_FIRST, }, -+ { .hook = ipv4_sabotage_out, -+ .pf = PF_INET, -+ .hooknum = NF_IP_FORWARD, -+ .priority = NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD, }, -+ { .hook = ipv4_sabotage_out, -+ .pf = PF_INET, -+ .hooknum = NF_IP_LOCAL_OUT, -+ .priority = NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, }, -+ { .hook = ipv4_sabotage_out, -+ .pf = PF_INET, -+ .hooknum = NF_IP_POST_ROUTING, -+ .priority = NF_IP_PRI_FIRST, }, -+}; -+ -+#ifdef CONFIG_SYSCTL -+static -+int brnf_sysctl_call_tables(ctl_table *ctl, int write, struct file * filp, -+ void *buffer, size_t *lenp) -+{ -+ int ret; -+ -+ ret = proc_dointvec(ctl, write, filp, buffer, lenp); -+ -+ if (write && *(int *)(ctl->data)) -+ *(int *)(ctl->data) = 1; -+ return ret; -+} -+ -+static ctl_table brnf_table[] = { -+ { -+ .ctl_name = NET_BRIDGE_NF_CALL_ARPTABLES, -+ .procname = "bridge-nf-call-arptables", -+ .data = &brnf_call_arptables, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &brnf_sysctl_call_tables, -+ }, -+ { -+ .ctl_name = NET_BRIDGE_NF_CALL_IPTABLES, -+ .procname = "bridge-nf-call-iptables", -+ .data = &brnf_call_iptables, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &brnf_sysctl_call_tables, -+ }, -+ { -+ .ctl_name = NET_BRIDGE_NF_FILTER_VLAN_TAGGED, -+ .procname = "bridge-nf-filter-vlan-tagged", -+ .data = &brnf_filter_vlan_tagged, -+ .maxlen = sizeof(int), -+ .mode = 0644, -+ .proc_handler = &brnf_sysctl_call_tables, -+ }, -+ { .ctl_name = 0 } -+}; -+ -+static ctl_table brnf_bridge_table[] = { -+ { -+ .ctl_name = NET_BRIDGE, -+ .procname = "bridge", -+ .mode = 0555, -+ .child = brnf_table, -+ }, -+ { .ctl_name = 0 } -+}; -+ -+static ctl_table brnf_net_table[] = { -+ { -+ .ctl_name = CTL_NET, -+ .procname = "net", -+ .mode = 0555, -+ .child = brnf_bridge_table, -+ }, -+ { .ctl_name = 0 } -+}; -+#endif -+ -+int br_netfilter_init(void) -+{ -+ int i; -+ -+ for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) { -+ int ret; -+ -+ if ((ret = nf_register_hook(&br_nf_ops[i])) >= 0) -+ continue; -+ -+ while (i--) -+ nf_unregister_hook(&br_nf_ops[i]); -+ -+ return ret; -+ } -+ -+#ifdef CONFIG_SYSCTL -+ brnf_sysctl_header = register_sysctl_table(brnf_net_table, 0); -+ if (brnf_sysctl_header == NULL) { -+ printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n"); -+ for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) -+ nf_unregister_hook(&br_nf_ops[i]); -+ return -EFAULT; -+ } -+#endif -+ -+ printk(KERN_NOTICE "Bridge firewalling registered\n"); -+ -+ return 0; -+} -+ -+void br_netfilter_fini(void) -+{ -+ int i; -+ -+ for (i = ARRAY_SIZE(br_nf_ops) - 1; i >= 0; i--) -+ nf_unregister_hook(&br_nf_ops[i]); -+#ifdef CONFIG_SYSCTL -+ unregister_sysctl_table(brnf_sysctl_header); -+#endif -+ -+} -diff -Nurb src/linux/linux.stock/net/bridge/br_private.h src/linux/linux/net/bridge/br_private.h ---- src/linux/linux.stock/net/bridge/br_private.h 2003-10-14 04:09:32.000000000 -0400 -+++ src/linux/linux/net/bridge/br_private.h 2004-07-10 23:46:39.000000000 -0400 -@@ -145,8 +145,10 @@ - /* br_forward.c */ - extern void br_deliver(struct net_bridge_port *to, - struct sk_buff *skb); -+extern int br_dev_queue_push_xmit(struct sk_buff *skb); - extern void br_forward(struct net_bridge_port *to, - struct sk_buff *skb); -+extern int br_forward_finish(struct sk_buff *skb); - extern void br_flood_deliver(struct net_bridge *br, - struct sk_buff *skb, - int clone); -@@ -167,7 +169,8 @@ - int *ifindices); - - /* br_input.c */ --extern void br_handle_frame(struct sk_buff *skb); -+extern int br_handle_frame_finish(struct sk_buff *skb); -+extern int br_handle_frame(struct sk_buff *skb); - - /* br_ioctl.c */ - extern void br_call_ioctl_atomic(void (*fn)(void)); -@@ -178,6 +181,10 @@ - unsigned long arg2); - extern int br_ioctl_deviceless_stub(unsigned long arg); - -+/* br_netfilter.c */ -+extern int br_netfilter_init(void); -+extern void br_netfilter_fini(void); -+ - /* br_stp.c */ - extern int br_is_root_bridge(struct net_bridge *br); - extern struct net_bridge_port *br_get_port(struct net_bridge *br, -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/Config.in src/linux/linux/net/bridge/netfilter/Config.in ---- src/linux/linux.stock/net/bridge/netfilter/Config.in 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/Config.in 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,22 @@ -+# -+# Bridge netfilter configuration -+# -+dep_tristate ' Bridge: ebtables' CONFIG_BRIDGE_NF_EBTABLES $CONFIG_BRIDGE -+dep_tristate ' ebt: filter table support' CONFIG_BRIDGE_EBT_T_FILTER $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: nat table support' CONFIG_BRIDGE_EBT_T_NAT $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: broute table support' CONFIG_BRIDGE_EBT_BROUTE $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: log support' CONFIG_BRIDGE_EBT_LOG $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: IP filter support' CONFIG_BRIDGE_EBT_IPF $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: ARP filter support' CONFIG_BRIDGE_EBT_ARPF $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: among filter support' CONFIG_BRIDGE_EBT_AMONG $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: limit filter support' CONFIG_BRIDGE_EBT_LIMIT $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: 802.1Q VLAN filter support' CONFIG_BRIDGE_EBT_VLANF $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: 802.3 filter support' CONFIG_BRIDGE_EBT_802_3 $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: packet type filter support' CONFIG_BRIDGE_EBT_PKTTYPE $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: STP filter support' CONFIG_BRIDGE_EBT_STP $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: mark filter support' CONFIG_BRIDGE_EBT_MARKF $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: arp reply target support' CONFIG_BRIDGE_EBT_ARPREPLY $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: snat target support' CONFIG_BRIDGE_EBT_SNAT $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: dnat target support' CONFIG_BRIDGE_EBT_DNAT $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: redirect target support' CONFIG_BRIDGE_EBT_REDIRECT $CONFIG_BRIDGE_NF_EBTABLES -+dep_tristate ' ebt: mark target support' CONFIG_BRIDGE_EBT_MARK_T $CONFIG_BRIDGE_NF_EBTABLES -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/Makefile src/linux/linux/net/bridge/netfilter/Makefile ---- src/linux/linux.stock/net/bridge/netfilter/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/Makefile 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,33 @@ -+# -+# Makefile for the netfilter modules on top of bridging. -+# -+# Note! Dependencies are done automagically by 'make dep', which also -+# removes any old dependencies. DON'T put your own dependencies here -+# unless it's something special (ie not a .c file). -+# -+# Note 2! The CFLAGS definition is now in the main makefile... -+ -+O_TARGET := netfilter.o -+ -+export-objs := ebtables.o -+ -+obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o -+obj-$(CONFIG_BRIDGE_EBT_T_FILTER) += ebtable_filter.o -+obj-$(CONFIG_BRIDGE_EBT_T_NAT) += ebtable_nat.o -+obj-$(CONFIG_BRIDGE_EBT_BROUTE) += ebtable_broute.o -+obj-$(CONFIG_BRIDGE_EBT_802_3) += ebt_802_3.o -+obj-$(CONFIG_BRIDGE_EBT_ARPF) += ebt_arp.o -+obj-$(CONFIG_BRIDGE_EBT_AMONG) += ebt_among.o -+obj-$(CONFIG_BRIDGE_EBT_IPF) += ebt_ip.o -+obj-$(CONFIG_BRIDGE_EBT_LIMIT) += ebt_limit.o -+obj-$(CONFIG_BRIDGE_EBT_MARKF) += ebt_mark_m.o -+obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o -+obj-$(CONFIG_BRIDGE_EBT_STP) += ebt_stp.o -+obj-$(CONFIG_BRIDGE_EBT_VLANF) += ebt_vlan.o -+obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o -+obj-$(CONFIG_BRIDGE_EBT_ARPREPLY) += ebt_arpreply.o -+obj-$(CONFIG_BRIDGE_EBT_DNAT) += ebt_dnat.o -+obj-$(CONFIG_BRIDGE_EBT_MARK_T) += ebt_mark.o -+obj-$(CONFIG_BRIDGE_EBT_REDIRECT) += ebt_redirect.o -+obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o -+include $(TOPDIR)/Rules.make -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_802_3.c src/linux/linux/net/bridge/netfilter/ebt_802_3.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_802_3.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_802_3.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,74 @@ -+/* -+ * 802_3 -+ * -+ * Author: -+ * Chris Vitale csv@bluetail.com -+ * -+ * May 2003 -+ * -+ */ -+ -+#include -+#include -+#include -+ -+static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in, -+ const struct net_device *out, const void *data, unsigned int datalen) -+{ -+ struct ebt_802_3_info *info = (struct ebt_802_3_info *)data; -+ struct ebt_802_3_hdr *hdr = (struct ebt_802_3_hdr *)skb->mac.ethernet; -+ uint16_t type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type; -+ -+ if (info->bitmask & EBT_802_3_SAP) { -+ if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP)) -+ return EBT_NOMATCH; -+ if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP)) -+ return EBT_NOMATCH; -+ } -+ -+ if (info->bitmask & EBT_802_3_TYPE) { -+ if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE)) -+ return EBT_NOMATCH; -+ if (FWINV(info->type != type, EBT_802_3_TYPE)) -+ return EBT_NOMATCH; -+ } -+ -+ return EBT_MATCH; -+} -+ -+static struct ebt_match filter_802_3; -+static int ebt_802_3_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_802_3_info *info = (struct ebt_802_3_info *)data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_802_3_info))) -+ return -EINVAL; -+ if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static struct ebt_match filter_802_3 = -+{ -+ .name = EBT_802_3_MATCH, -+ .match = ebt_filter_802_3, -+ .check = ebt_802_3_check, -+ .me = THIS_MODULE, -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_match(&filter_802_3); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_match(&filter_802_3); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_among.c src/linux/linux/net/bridge/netfilter/ebt_among.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_among.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_among.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,223 @@ -+/* -+ * ebt_among -+ * -+ * Authors: -+ * Grzegorz Borowiak -+ * -+ * August, 2003 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, -+ const char *mac, uint32_t ip) -+{ -+ /* You may be puzzled as to how this code works. -+ * Some tricks were used, refer to -+ * include/linux/netfilter_bridge/ebt_among.h -+ * as there you can find a solution of this mystery. -+ */ -+ const struct ebt_mac_wormhash_tuple *p; -+ int start, limit, i; -+ uint32_t cmp[2] = { 0, 0 }; -+ int key = (const unsigned char) mac[5]; -+ -+ memcpy(((char *) cmp) + 2, mac, 6); -+ start = wh->table[key]; -+ limit = wh->table[key + 1]; -+ if (ip) { -+ for (i = start; i < limit; i++) { -+ p = &wh->pool[i]; -+ if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { -+ if (p->ip == 0 || p->ip == ip) { -+ return 1; -+ } -+ } -+ } -+ } else { -+ for (i = start; i < limit; i++) { -+ p = &wh->pool[i]; -+ if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { -+ if (p->ip == 0) { -+ return 1; -+ } -+ } -+ } -+ } -+ return 0; -+} -+ -+static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash -+ *wh) -+{ -+ int i; -+ -+ for (i = 0; i < 256; i++) { -+ if (wh->table[i] > wh->table[i + 1]) -+ return -0x100 - i; -+ if (wh->table[i] < 0) -+ return -0x200 - i; -+ if (wh->table[i] > wh->poolsize) -+ return -0x300 - i; -+ } -+ if (wh->table[256] > wh->poolsize) -+ return -0xc00; -+ return 0; -+} -+ -+static int get_ip_dst(const struct sk_buff *skb, uint32_t * addr) -+{ -+ if (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_IP)) -+ *addr = skb->nh.iph->daddr; -+ else if (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_ARP)) { -+ uint32_t arp_len = sizeof(struct arphdr) + -+ (2 * (((*skb).nh.arph)->ar_hln)) + -+ (2 * (((*skb).nh.arph)->ar_pln)); -+ -+ /* Make sure the packet is long enough. */ -+ if ((((*skb).nh.raw) + arp_len) > (*skb).tail) -+ return -1; -+ /* IPv4 addresses are always 4 bytes. */ -+ if (((*skb).nh.arph)->ar_pln != sizeof(uint32_t)) -+ return -1; -+ -+ memcpy(addr, ((*skb).nh.raw) + sizeof(struct arphdr) + -+ (2 * (((*skb).nh.arph)->ar_hln)) + -+ (((*skb).nh.arph)->ar_pln), sizeof(uint32_t)); -+ -+ } -+ return 0; -+} -+ -+static int get_ip_src(const struct sk_buff *skb, uint32_t * addr) -+{ -+ if (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_IP)) -+ *addr = skb->nh.iph->saddr; -+ else if (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_ARP)) { -+ uint32_t arp_len = sizeof(struct arphdr) + -+ (2 * (((*skb).nh.arph)->ar_hln)) + -+ (2 * (((*skb).nh.arph)->ar_pln)); -+ -+ /* Make sure the packet is long enough. */ -+ if ((((*skb).nh.raw) + arp_len) > (*skb).tail) -+ return -1; -+ /* IPv4 addresses are always 4 bytes. */ -+ if (((*skb).nh.arph)->ar_pln != sizeof(uint32_t)) -+ return -1; -+ -+ memcpy(addr, ((*skb).nh.raw) + sizeof(struct arphdr) + -+ ((((*skb).nh.arph)->ar_hln)), sizeof(uint32_t)); -+ -+ } -+ return 0; -+} -+ -+static int ebt_filter_among(const struct sk_buff *skb, -+ const struct net_device *in, -+ const struct net_device *out, const void *data, -+ unsigned int datalen) -+{ -+ struct ebt_among_info *info = (struct ebt_among_info *) data; -+ const char *dmac, *smac; -+ const struct ebt_mac_wormhash *wh_dst, *wh_src; -+ uint32_t dip = 0, sip = 0; -+ -+ wh_dst = ebt_among_wh_dst(info); -+ wh_src = ebt_among_wh_src(info); -+ -+ if (wh_src) { -+ smac = skb->mac.ethernet->h_source; -+ if (get_ip_src(skb, &sip)) -+ return EBT_NOMATCH; -+ if (!(info->bitmask & EBT_AMONG_SRC_NEG)) { -+ /* we match only if it contains */ -+ if (!ebt_mac_wormhash_contains(wh_src, smac, sip)) -+ return EBT_NOMATCH; -+ } else { -+ /* we match only if it DOES NOT contain */ -+ if (ebt_mac_wormhash_contains(wh_src, smac, sip)) -+ return EBT_NOMATCH; -+ } -+ } -+ -+ if (wh_dst) { -+ dmac = skb->mac.ethernet->h_dest; -+ if (get_ip_dst(skb, &dip)) -+ return EBT_NOMATCH; -+ if (!(info->bitmask & EBT_AMONG_DST_NEG)) { -+ /* we match only if it contains */ -+ if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip)) -+ return EBT_NOMATCH; -+ } else { -+ /* we match only if it DOES NOT contain */ -+ if (ebt_mac_wormhash_contains(wh_dst, dmac, dip)) -+ return EBT_NOMATCH; -+ } -+ } -+ -+ return EBT_MATCH; -+} -+ -+static int ebt_among_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, -+ unsigned int datalen) -+{ -+ struct ebt_among_info *info = (struct ebt_among_info *) data; -+ int expected_length = sizeof(struct ebt_among_info); -+ const struct ebt_mac_wormhash *wh_dst, *wh_src; -+ int err; -+ -+ wh_dst = ebt_among_wh_dst(info); -+ wh_src = ebt_among_wh_src(info); -+ expected_length += ebt_mac_wormhash_size(wh_dst); -+ expected_length += ebt_mac_wormhash_size(wh_src); -+ -+ if (datalen != EBT_ALIGN(expected_length)) { -+ printk(KERN_WARNING -+ "ebtables: among: wrong size: %d" -+ "against expected %d, rounded to %d\n", -+ datalen, expected_length, -+ EBT_ALIGN(expected_length)); -+ return -EINVAL; -+ } -+ if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) { -+ printk(KERN_WARNING -+ "ebtables: among: dst integrity fail: %x\n", -err); -+ return -EINVAL; -+ } -+ if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) { -+ printk(KERN_WARNING -+ "ebtables: among: src integrity fail: %x\n", -err); -+ return -EINVAL; -+ } -+ return 0; -+} -+ -+static struct ebt_match filter_among = { -+ {NULL, NULL}, -+ EBT_AMONG_MATCH, -+ ebt_filter_among, -+ ebt_among_check, -+ NULL, -+ THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_match(&filter_among); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_match(&filter_among); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_arp.c src/linux/linux/net/bridge/netfilter/ebt_arp.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_arp.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_arp.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,149 @@ -+/* -+ * ebt_arp -+ * -+ * Authors: -+ * Bart De Schuymer -+ * Tim Gardner -+ * -+ * April, 2002 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in, -+ const struct net_device *out, const void *data, unsigned int datalen) -+{ -+ struct ebt_arp_info *info = (struct ebt_arp_info *)data; -+ -+ if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode != -+ ((*skb).nh.arph)->ar_op, EBT_ARP_OPCODE)) -+ return EBT_NOMATCH; -+ if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype != -+ ((*skb).nh.arph)->ar_hrd, EBT_ARP_HTYPE)) -+ return EBT_NOMATCH; -+ if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype != -+ ((*skb).nh.arph)->ar_pro, EBT_ARP_PTYPE)) -+ return EBT_NOMATCH; -+ -+ if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) -+ { -+ uint32_t arp_len = sizeof(struct arphdr) + -+ (2 * (((*skb).nh.arph)->ar_hln)) + -+ (2 * (((*skb).nh.arph)->ar_pln)); -+ uint32_t dst; -+ uint32_t src; -+ -+ // Make sure the packet is long enough. -+ if ((((*skb).nh.raw) + arp_len) > (*skb).tail) -+ return EBT_NOMATCH; -+ // IPv4 addresses are always 4 bytes. -+ if (((*skb).nh.arph)->ar_pln != sizeof(uint32_t)) -+ return EBT_NOMATCH; -+ -+ if (info->bitmask & EBT_ARP_SRC_IP) { -+ memcpy(&src, ((*skb).nh.raw) + sizeof(struct arphdr) + -+ ((*skb).nh.arph)->ar_hln, sizeof(uint32_t)); -+ if (FWINV(info->saddr != (src & info->smsk), -+ EBT_ARP_SRC_IP)) -+ return EBT_NOMATCH; -+ } -+ -+ if (info->bitmask & EBT_ARP_DST_IP) { -+ memcpy(&dst, ((*skb).nh.raw)+sizeof(struct arphdr) + -+ (2*(((*skb).nh.arph)->ar_hln)) + -+ (((*skb).nh.arph)->ar_pln), sizeof(uint32_t)); -+ if (FWINV(info->daddr != (dst & info->dmsk), -+ EBT_ARP_DST_IP)) -+ return EBT_NOMATCH; -+ } -+ } -+ -+ if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) -+ { -+ uint32_t arp_len = sizeof(struct arphdr) + -+ (2 * (((*skb).nh.arph)->ar_hln)) + -+ (2 * (((*skb).nh.arph)->ar_pln)); -+ unsigned char dst[ETH_ALEN]; -+ unsigned char src[ETH_ALEN]; -+ -+ // Make sure the packet is long enough. -+ if ((((*skb).nh.raw) + arp_len) > (*skb).tail) -+ return EBT_NOMATCH; -+ // MAC addresses are 6 bytes. -+ if (((*skb).nh.arph)->ar_hln != ETH_ALEN) -+ return EBT_NOMATCH; -+ if (info->bitmask & EBT_ARP_SRC_MAC) { -+ uint8_t verdict, i; -+ -+ memcpy(&src, ((*skb).nh.raw) + -+ sizeof(struct arphdr), -+ ETH_ALEN); -+ verdict = 0; -+ for (i = 0; i < 6; i++) -+ verdict |= (src[i] ^ info->smaddr[i]) & -+ info->smmsk[i]; -+ if (FWINV(verdict != 0, EBT_ARP_SRC_MAC)) -+ return EBT_NOMATCH; -+ } -+ -+ if (info->bitmask & EBT_ARP_DST_MAC) { -+ uint8_t verdict, i; -+ -+ memcpy(&dst, ((*skb).nh.raw) + -+ sizeof(struct arphdr) + -+ (((*skb).nh.arph)->ar_hln) + -+ (((*skb).nh.arph)->ar_pln), -+ ETH_ALEN); -+ verdict = 0; -+ for (i = 0; i < 6; i++) -+ verdict |= (dst[i] ^ info->dmaddr[i]) & -+ info->dmmsk[i]; -+ if (FWINV(verdict != 0, EBT_ARP_DST_MAC)) -+ return EBT_NOMATCH; -+ } -+ } -+ -+ return EBT_MATCH; -+} -+ -+static int ebt_arp_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_arp_info *info = (struct ebt_arp_info *)data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info))) -+ return -EINVAL; -+ if ((e->ethproto != __constant_htons(ETH_P_ARP) && -+ e->ethproto != __constant_htons(ETH_P_RARP)) || -+ e->invflags & EBT_IPROTO) -+ return -EINVAL; -+ if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_match filter_arp = -+{ -+ {NULL, NULL}, EBT_ARP_MATCH, ebt_filter_arp, ebt_arp_check, NULL, -+ THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_match(&filter_arp); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_match(&filter_arp); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_arpreply.c src/linux/linux/net/bridge/netfilter/ebt_arpreply.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_arpreply.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_arpreply.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,86 @@ -+/* -+ * ebt_arpreply -+ * -+ * Authors: -+ * Grzegorz Borowiak -+ * Bart De Schuymer -+ * -+ * August, 2003 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static int ebt_target_reply(struct sk_buff **pskb, unsigned int hooknr, -+ const struct net_device *in, const struct net_device *out, -+ const void *data, unsigned int datalen) -+{ -+ struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data; -+ struct arphdr *ah; -+ unsigned char *sha, *arp_ptr; -+ u32 sip, tip; -+ -+ ah = (**pskb).nh.arph; -+ if (ah->ar_op != __constant_htons(ARPOP_REQUEST) || -+ ah->ar_hln != ETH_ALEN || ah->ar_pro != htons(ETH_P_IP) || -+ ah->ar_pln != 4) -+ return EBT_CONTINUE; -+ -+ arp_ptr = (unsigned char *)(ah + 1); -+ -+ /* get source and target IP */ -+ sha = arp_ptr; -+ arp_ptr += ETH_ALEN; -+ memcpy(&sip, arp_ptr, 4); -+ arp_ptr += 4 + ETH_ALEN; -+ memcpy(&tip, arp_ptr, 4); -+ -+ arp_send(ARPOP_REPLY, ETH_P_ARP, sip, in, tip, sha, info->mac, sha); -+ -+ return info->target; -+} -+ -+static int ebt_target_reply_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_arpreply_info))) -+ return -EINVAL; -+ if (BASE_CHAIN && info->target == EBT_RETURN) -+ return -EINVAL; -+ if (e->ethproto != __constant_htons(ETH_P_ARP) || -+ e->invflags & EBT_IPROTO) -+ return -EINVAL; -+ CLEAR_BASE_CHAIN_BIT; -+ if (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_target reply_target = -+{ -+ .name = EBT_ARPREPLY_TARGET, -+ .target = ebt_target_reply, -+ .check = ebt_target_reply_check, -+ .me = THIS_MODULE, -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_target(&reply_target); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_target(&reply_target); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_dnat.c src/linux/linux/net/bridge/netfilter/ebt_dnat.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_dnat.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_dnat.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,65 @@ -+/* -+ * ebt_dnat -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * June, 2002 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+ -+static int ebt_target_dnat(struct sk_buff **pskb, unsigned int hooknr, -+ const struct net_device *in, const struct net_device *out, -+ const void *data, unsigned int datalen) -+{ -+ struct ebt_nat_info *info = (struct ebt_nat_info *)data; -+ -+ memcpy(((**pskb).mac.ethernet)->h_dest, info->mac, -+ ETH_ALEN * sizeof(unsigned char)); -+ return info->target; -+} -+ -+static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_nat_info *info = (struct ebt_nat_info *)data; -+ -+ if (BASE_CHAIN && info->target == EBT_RETURN) -+ return -EINVAL; -+ CLEAR_BASE_CHAIN_BIT; -+ if ( (strcmp(tablename, "nat") || -+ (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) && -+ (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) -+ return -EINVAL; -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info))) -+ return -EINVAL; -+ if (INVALID_TARGET) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_target dnat = -+{ -+ {NULL, NULL}, EBT_DNAT_TARGET, ebt_target_dnat, ebt_target_dnat_check, -+ NULL, THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_target(&dnat); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_target(&dnat); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_ip.c src/linux/linux/net/bridge/netfilter/ebt_ip.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_ip.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_ip.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,121 @@ -+/* -+ * ebt_ip -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * April, 2002 -+ * -+ * Changes: -+ * added ip-sport and ip-dport -+ * Innominate Security Technologies AG -+ * September, 2002 -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+struct tcpudphdr { -+ uint16_t src; -+ uint16_t dst; -+}; -+ -+union h_u { -+ unsigned char *raw; -+ struct tcpudphdr *tuh; -+}; -+ -+static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, -+ const struct net_device *out, const void *data, -+ unsigned int datalen) -+{ -+ struct ebt_ip_info *info = (struct ebt_ip_info *)data; -+ -+ if (info->bitmask & EBT_IP_TOS && -+ FWINV(info->tos != ((*skb).nh.iph)->tos, EBT_IP_TOS)) -+ return EBT_NOMATCH; -+ if (info->bitmask & EBT_IP_PROTO) { -+ if (FWINV(info->protocol != ((*skb).nh.iph)->protocol, -+ EBT_IP_PROTO)) -+ return EBT_NOMATCH; -+ if ( info->protocol == IPPROTO_TCP || -+ info->protocol == IPPROTO_UDP ) -+ { -+ union h_u h; -+ h.raw = skb->data + skb->nh.iph->ihl*4; -+ if (info->bitmask & EBT_IP_DPORT) { -+ uint16_t port = ntohs(h.tuh->dst); -+ if (FWINV(port < info->dport[0] || -+ port > info->dport[1], -+ EBT_IP_DPORT)) -+ return EBT_NOMATCH; -+ } -+ if (info->bitmask & EBT_IP_SPORT) { -+ uint16_t port = ntohs(h.tuh->src); -+ if (FWINV(port < info->sport[0] || -+ port > info->sport[1], -+ EBT_IP_SPORT)) -+ return EBT_NOMATCH; -+ } -+ } -+ } -+ if (info->bitmask & EBT_IP_SOURCE && -+ FWINV((((*skb).nh.iph)->saddr & info->smsk) != -+ info->saddr, EBT_IP_SOURCE)) -+ return EBT_NOMATCH; -+ if ((info->bitmask & EBT_IP_DEST) && -+ FWINV((((*skb).nh.iph)->daddr & info->dmsk) != -+ info->daddr, EBT_IP_DEST)) -+ return EBT_NOMATCH; -+ return EBT_MATCH; -+} -+ -+static int ebt_ip_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_ip_info *info = (struct ebt_ip_info *)data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info))) -+ return -EINVAL; -+ if (e->ethproto != __constant_htons(ETH_P_IP) || -+ e->invflags & EBT_IPROTO) -+ return -EINVAL; -+ if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK) -+ return -EINVAL; -+ if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) { -+ if (!info->bitmask & EBT_IPROTO) -+ return -EINVAL; -+ if (info->protocol != IPPROTO_TCP && -+ info->protocol != IPPROTO_UDP) -+ return -EINVAL; -+ } -+ if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1]) -+ return -EINVAL; -+ if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1]) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_match filter_ip = -+{ -+ {NULL, NULL}, EBT_IP_MATCH, ebt_filter_ip, ebt_ip_check, NULL, -+ THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_match(&filter_ip); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_match(&filter_ip); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_limit.c src/linux/linux/net/bridge/netfilter/ebt_limit.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_limit.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_limit.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,101 @@ -+/* -+ * ebt_limit -+ * -+ * Authors: -+ * Tom Marshall -+ * -+ * Mostly copied from netfilter's ipt_limit.c, see that file for explanation -+ * -+ * September, 2003 -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+ -+static spinlock_t limit_lock = SPIN_LOCK_UNLOCKED; -+ -+#define CREDITS_PER_JIFFY 128 -+ -+static int ebt_limit_match(const struct sk_buff *skb, const struct net_device *in, -+ const struct net_device *out, const void *data, unsigned int datalen) -+{ -+ struct ebt_limit_info *info = (struct ebt_limit_info *)data; -+ unsigned long now = jiffies; -+ -+ spin_lock_bh(&limit_lock); -+ info->credit += (now - xchg(&info->prev, now)) * CREDITS_PER_JIFFY; -+ if (info->credit > info->credit_cap) -+ info->credit = info->credit_cap; -+ -+ if (info->credit >= info->cost) { -+ /* We're not limited. */ -+ info->credit -= info->cost; -+ spin_unlock_bh(&limit_lock); -+ return EBT_MATCH; -+ } -+ -+ spin_unlock_bh(&limit_lock); -+ return EBT_NOMATCH; -+} -+ -+/* Precision saver. */ -+static u_int32_t -+user2credits(u_int32_t user) -+{ -+ /* If multiplying would overflow... */ -+ if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) -+ /* Divide first. */ -+ return (user / EBT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; -+ -+ return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; -+} -+ -+static int ebt_limit_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_limit_info *info = (struct ebt_limit_info *)data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info))) -+ return -EINVAL; -+ -+ /* Check for overflow. */ -+ if (info->burst == 0 -+ || user2credits(info->avg * info->burst) < user2credits(info->avg)) { -+ printk("Overflow in ebt_limit: %u/%u\n", -+ info->avg, info->burst); -+ return -EINVAL; -+ } -+ -+ /* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */ -+ info->prev = jiffies; -+ info->credit = user2credits(info->avg * info->burst); -+ info->credit_cap = user2credits(info->avg * info->burst); -+ info->cost = user2credits(info->avg); -+ return 0; -+} -+ -+static struct ebt_match ebt_limit_reg = -+{ -+ {NULL, NULL}, EBT_LIMIT_MATCH, ebt_limit_match, ebt_limit_check, NULL, -+ THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_match(&ebt_limit_reg); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_match(&ebt_limit_reg); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_log.c src/linux/linux/net/bridge/netfilter/ebt_log.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_log.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_log.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,152 @@ -+/* -+ * ebt_log -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * April, 2002 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static spinlock_t ebt_log_lock = SPIN_LOCK_UNLOCKED; -+ -+static int ebt_log_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_log_info *info = (struct ebt_log_info *)data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info))) -+ return -EINVAL; -+ if (info->bitmask & ~EBT_LOG_MASK) -+ return -EINVAL; -+ if (info->loglevel >= 8) -+ return -EINVAL; -+ info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0'; -+ return 0; -+} -+ -+struct tcpudphdr -+{ -+ uint16_t src; -+ uint16_t dst; -+}; -+ -+struct arppayload -+{ -+ unsigned char mac_src[ETH_ALEN]; -+ unsigned char ip_src[4]; -+ unsigned char mac_dst[ETH_ALEN]; -+ unsigned char ip_dst[4]; -+}; -+ -+static void print_MAC(unsigned char *p) -+{ -+ int i; -+ -+ for (i = 0; i < ETH_ALEN; i++, p++) -+ printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':'); -+} -+ -+#define myNIPQUAD(a) a[0], a[1], a[2], a[3] -+static void ebt_log(const struct sk_buff *skb, const struct net_device *in, -+ const struct net_device *out, const void *data, unsigned int datalen) -+{ -+ struct ebt_log_info *info = (struct ebt_log_info *)data; -+ char level_string[4] = "< >"; -+ level_string[1] = '0' + info->loglevel; -+ -+ spin_lock_bh(&ebt_log_lock); -+ printk(level_string); -+ printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "", -+ out ? out->name : ""); -+ -+ printk("MAC source = "); -+ print_MAC((skb->mac.ethernet)->h_source); -+ printk("MAC dest = "); -+ print_MAC((skb->mac.ethernet)->h_dest); -+ -+ printk("proto = 0x%04x", ntohs(((*skb).mac.ethernet)->h_proto)); -+ -+ if ((info->bitmask & EBT_LOG_IP) && skb->mac.ethernet->h_proto == -+ htons(ETH_P_IP)){ -+ struct iphdr *iph = skb->nh.iph; -+ printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", -+ NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); -+ printk(" IP tos=0x%02X, IP proto=%d", iph->tos, iph->protocol); -+ if (iph->protocol == IPPROTO_TCP || -+ iph->protocol == IPPROTO_UDP) { -+ struct tcpudphdr *ports = (struct tcpudphdr *)(skb->data + iph->ihl*4); -+ -+ if (skb->data + iph->ihl*4 > skb->tail) { -+ printk(" INCOMPLETE TCP/UDP header"); -+ goto out; -+ } -+ printk(" SPT=%u DPT=%u", ntohs(ports->src), -+ ntohs(ports->dst)); -+ } -+ goto out; -+ } -+ -+ if ((info->bitmask & EBT_LOG_ARP) && -+ ((skb->mac.ethernet->h_proto == __constant_htons(ETH_P_ARP)) || -+ (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_RARP)))) { -+ struct arphdr * arph = skb->nh.arph; -+ printk(" ARP HTYPE=%d, PTYPE=0x%04x, OPCODE=%d", -+ ntohs(arph->ar_hrd), ntohs(arph->ar_pro), -+ ntohs(arph->ar_op)); -+ /* If it's for Ethernet and the lengths are OK, -+ * then log the ARP payload */ -+ if (arph->ar_hrd == __constant_htons(1) && -+ arph->ar_hln == ETH_ALEN && -+ arph->ar_pln == sizeof(uint32_t)) { -+ struct arppayload *arpp = (struct arppayload *)(skb->data + sizeof(*arph)); -+ -+ if (skb->data + sizeof(*arph) > skb->tail) { -+ printk(" INCOMPLETE ARP header"); -+ goto out; -+ } -+ -+ printk(" ARP MAC SRC="); -+ print_MAC(arpp->mac_src); -+ printk(" ARP IP SRC=%u.%u.%u.%u", -+ myNIPQUAD(arpp->ip_src)); -+ printk(" ARP MAC DST="); -+ print_MAC(arpp->mac_dst); -+ printk(" ARP IP DST=%u.%u.%u.%u", -+ myNIPQUAD(arpp->ip_dst)); -+ } -+ -+ } -+out: -+ printk("\n"); -+ spin_unlock_bh(&ebt_log_lock); -+} -+ -+static struct ebt_watcher log = -+{ -+ {NULL, NULL}, EBT_LOG_WATCHER, ebt_log, ebt_log_check, NULL, -+ THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_watcher(&log); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_watcher(&log); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_mark.c src/linux/linux/net/bridge/netfilter/ebt_mark.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_mark.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_mark.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,66 @@ -+/* -+ * ebt_mark -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * July, 2002 -+ * -+ */ -+ -+// The mark target can be used in any chain -+// I believe adding a mangle table just for marking is total overkill -+// Marking a frame doesn't really change anything in the frame anyway -+ -+#include -+#include -+#include -+ -+static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr, -+ const struct net_device *in, const struct net_device *out, -+ const void *data, unsigned int datalen) -+{ -+ struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data; -+ -+ if ((*pskb)->nfmark != info->mark) { -+ (*pskb)->nfmark = info->mark; -+ (*pskb)->nfcache |= NFC_ALTERED; -+ } -+ return info->target; -+} -+ -+static int ebt_target_mark_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info))) -+ return -EINVAL; -+ if (BASE_CHAIN && info->target == EBT_RETURN) -+ return -EINVAL; -+ CLEAR_BASE_CHAIN_BIT; -+ if (INVALID_TARGET) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_target mark_target = -+{ -+ {NULL, NULL}, EBT_MARK_TARGET, ebt_target_mark, -+ ebt_target_mark_check, NULL, THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_target(&mark_target); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_target(&mark_target); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_mark_m.c src/linux/linux/net/bridge/netfilter/ebt_mark_m.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_mark_m.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_mark_m.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,61 @@ -+/* -+ * ebt_mark_m -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * July, 2002 -+ * -+ */ -+ -+#include -+#include -+#include -+ -+static int ebt_filter_mark(const struct sk_buff *skb, -+ const struct net_device *in, const struct net_device *out, const void *data, -+ unsigned int datalen) -+{ -+ struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data; -+ -+ if (info->bitmask & EBT_MARK_OR) -+ return !(!!(skb->nfmark & info->mask) ^ info->invert); -+ return !(((skb->nfmark & info->mask) == info->mark) ^ info->invert); -+} -+ -+static int ebt_mark_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_m_info))) -+ return -EINVAL; -+ if (info->bitmask & ~EBT_MARK_MASK) -+ return -EINVAL; -+ if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND)) -+ return -EINVAL; -+ if (!info->bitmask) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_match filter_mark = -+{ -+ {NULL, NULL}, EBT_MARK_MATCH, ebt_filter_mark, ebt_mark_check, NULL, -+ THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_match(&filter_mark); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_match(&filter_mark); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_pkttype.c src/linux/linux/net/bridge/netfilter/ebt_pkttype.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_pkttype.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_pkttype.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,60 @@ -+/* -+ * ebt_pkttype -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * April, 2003 -+ * -+ */ -+ -+#include -+#include -+#include -+ -+static int ebt_filter_pkttype(const struct sk_buff *skb, -+ const struct net_device *in, -+ const struct net_device *out, -+ const void *data, -+ unsigned int datalen) -+{ -+ struct ebt_pkttype_info *info = (struct ebt_pkttype_info *)data; -+ -+ return (skb->pkt_type != info->pkt_type) ^ info->invert; -+} -+ -+static int ebt_pkttype_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_pkttype_info *info = (struct ebt_pkttype_info *)data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_pkttype_info))) -+ return -EINVAL; -+ if (info->invert != 0 && info->invert != 1) -+ return -EINVAL; -+ /* Allow any pkt_type value */ -+ return 0; -+} -+ -+static struct ebt_match filter_pkttype = -+{ -+ .name = EBT_PKTTYPE_MATCH, -+ .match = ebt_filter_pkttype, -+ .check = ebt_pkttype_check, -+ .me = THIS_MODULE, -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_match(&filter_pkttype); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_match(&filter_pkttype); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_redirect.c src/linux/linux/net/bridge/netfilter/ebt_redirect.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_redirect.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_redirect.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,71 @@ -+/* -+ * ebt_redirect -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * April, 2002 -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include "../br_private.h" -+ -+static int ebt_target_redirect(struct sk_buff **pskb, unsigned int hooknr, -+ const struct net_device *in, const struct net_device *out, -+ const void *data, unsigned int datalen) -+{ -+ struct ebt_redirect_info *info = (struct ebt_redirect_info *)data; -+ -+ if (hooknr != NF_BR_BROUTING) -+ memcpy((**pskb).mac.ethernet->h_dest, -+ in->br_port->br->dev.dev_addr, ETH_ALEN); -+ else { -+ memcpy((**pskb).mac.ethernet->h_dest, -+ in->dev_addr, ETH_ALEN); -+ (*pskb)->pkt_type = PACKET_HOST; -+ } -+ return info->target; -+} -+ -+static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_redirect_info *info = (struct ebt_redirect_info *)data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_redirect_info))) -+ return -EINVAL; -+ if (BASE_CHAIN && info->target == EBT_RETURN) -+ return -EINVAL; -+ CLEAR_BASE_CHAIN_BIT; -+ if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) && -+ (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) -+ return -EINVAL; -+ if (INVALID_TARGET) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_target redirect_target = -+{ -+ {NULL, NULL}, EBT_REDIRECT_TARGET, ebt_target_redirect, -+ ebt_target_redirect_check, NULL, THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_target(&redirect_target); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_target(&redirect_target); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_snat.c src/linux/linux/net/bridge/netfilter/ebt_snat.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_snat.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_snat.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,64 @@ -+/* -+ * ebt_snat -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * June, 2002 -+ * -+ */ -+ -+#include -+#include -+#include -+ -+static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr, -+ const struct net_device *in, const struct net_device *out, -+ const void *data, unsigned int datalen) -+{ -+ struct ebt_nat_info *info = (struct ebt_nat_info *) data; -+ -+ memcpy(((**pskb).mac.ethernet)->h_source, info->mac, -+ ETH_ALEN * sizeof(unsigned char)); -+ return info->target; -+} -+ -+static int ebt_target_snat_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_nat_info *info = (struct ebt_nat_info *) data; -+ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info))) -+ return -EINVAL; -+ if (BASE_CHAIN && info->target == EBT_RETURN) -+ return -EINVAL; -+ CLEAR_BASE_CHAIN_BIT; -+ if (strcmp(tablename, "nat")) -+ return -EINVAL; -+ if (hookmask & ~(1 << NF_BR_POST_ROUTING)) -+ return -EINVAL; -+ if (INVALID_TARGET) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_target snat = -+{ -+ {NULL, NULL}, EBT_SNAT_TARGET, ebt_target_snat, ebt_target_snat_check, -+ NULL, THIS_MODULE -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_target(&snat); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_target(&snat); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_stp.c src/linux/linux/net/bridge/netfilter/ebt_stp.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_stp.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_stp.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,191 @@ -+/* -+ * ebt_stp -+ * -+ * Authors: -+ * Bart De Schuymer -+ * Stephen Hemminger -+ * -+ * June, 2003 -+ */ -+ -+#include -+#include -+#include -+ -+#define BPDU_TYPE_CONFIG 0 -+#define BPDU_TYPE_TCN 0x80 -+ -+struct stp_header { -+ uint8_t dsap; -+ uint8_t ssap; -+ uint8_t ctrl; -+ uint8_t pid; -+ uint8_t vers; -+ uint8_t type; -+}; -+ -+struct stp_config_pdu { -+ uint8_t flags; -+ uint8_t root[8]; -+ uint8_t root_cost[4]; -+ uint8_t sender[8]; -+ uint8_t port[2]; -+ uint8_t msg_age[2]; -+ uint8_t max_age[2]; -+ uint8_t hello_time[2]; -+ uint8_t forward_delay[2]; -+}; -+ -+#define NR16(p) (p[0] << 8 | p[1]) -+#define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]) -+ -+static int ebt_filter_config(struct ebt_stp_info *info, -+ struct stp_config_pdu *stpc) -+{ -+ struct ebt_stp_config_info *c; -+ uint16_t v16; -+ uint32_t v32; -+ int verdict, i; -+ -+ c = &info->config; -+ if ((info->bitmask & EBT_STP_FLAGS) && -+ FWINV(c->flags != stpc->flags, EBT_STP_FLAGS)) -+ return EBT_NOMATCH; -+ if (info->bitmask & EBT_STP_ROOTPRIO) { -+ v16 = NR16(stpc->root); -+ if (FWINV(v16 < c->root_priol || -+ v16 > c->root_priou, EBT_STP_ROOTPRIO)) -+ return EBT_NOMATCH; -+ } -+ if (info->bitmask & EBT_STP_ROOTADDR) { -+ verdict = 0; -+ for (i = 0; i < 6; i++) -+ verdict |= (stpc->root[2+i] ^ c->root_addr[i]) & -+ c->root_addrmsk[i]; -+ if (FWINV(verdict != 0, EBT_STP_ROOTADDR)) -+ return EBT_NOMATCH; -+ } -+ if (info->bitmask & EBT_STP_ROOTCOST) { -+ v32 = NR32(stpc->root_cost); -+ if (FWINV(v32 < c->root_costl || -+ v32 > c->root_costu, EBT_STP_ROOTCOST)) -+ return EBT_NOMATCH; -+ } -+ if (info->bitmask & EBT_STP_SENDERPRIO) { -+ v16 = NR16(stpc->sender); -+ if (FWINV(v16 < c->sender_priol || -+ v16 > c->sender_priou, EBT_STP_SENDERPRIO)) -+ return EBT_NOMATCH; -+ } -+ if (info->bitmask & EBT_STP_SENDERADDR) { -+ verdict = 0; -+ for (i = 0; i < 6; i++) -+ verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) & -+ c->sender_addrmsk[i]; -+ if (FWINV(verdict != 0, EBT_STP_SENDERADDR)) -+ return EBT_NOMATCH; -+ } -+ if (info->bitmask & EBT_STP_PORT) { -+ v16 = NR16(stpc->port); -+ if (FWINV(v16 < c->portl || -+ v16 > c->portu, EBT_STP_PORT)) -+ return EBT_NOMATCH; -+ } -+ if (info->bitmask & EBT_STP_MSGAGE) { -+ v16 = NR16(stpc->msg_age); -+ if (FWINV(v16 < c->msg_agel || -+ v16 > c->msg_ageu, EBT_STP_MSGAGE)) -+ return EBT_NOMATCH; -+ } -+ if (info->bitmask & EBT_STP_MAXAGE) { -+ v16 = NR16(stpc->max_age); -+ if (FWINV(v16 < c->max_agel || -+ v16 > c->max_ageu, EBT_STP_MAXAGE)) -+ return EBT_NOMATCH; -+ } -+ if (info->bitmask & EBT_STP_HELLOTIME) { -+ v16 = NR16(stpc->hello_time); -+ if (FWINV(v16 < c->hello_timel || -+ v16 > c->hello_timeu, EBT_STP_HELLOTIME)) -+ return EBT_NOMATCH; -+ } -+ if (info->bitmask & EBT_STP_FWDD) { -+ v16 = NR16(stpc->forward_delay); -+ if (FWINV(v16 < c->forward_delayl || -+ v16 > c->forward_delayu, EBT_STP_FWDD)) -+ return EBT_NOMATCH; -+ } -+ return EBT_MATCH; -+} -+ -+static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in, -+ const struct net_device *out, const void *data, unsigned int datalen) -+{ -+ struct ebt_stp_info *info = (struct ebt_stp_info *)data; -+ struct stp_header stph; -+ uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00}; -+ if (skb_copy_bits(skb, 0, &stph, sizeof(stph))) -+ return EBT_NOMATCH; -+ -+ /* The stp code only considers these */ -+ if (memcmp(&stph, header, sizeof(header))) -+ return EBT_NOMATCH; -+ -+ if (info->bitmask & EBT_STP_TYPE -+ && FWINV(info->type != stph.type, EBT_STP_TYPE)) -+ return EBT_NOMATCH; -+ -+ if (stph.type == BPDU_TYPE_CONFIG && -+ info->bitmask & EBT_STP_CONFIG_MASK) { -+ struct stp_config_pdu stpc; -+ -+ if (skb_copy_bits(skb, sizeof(stph), &stpc, sizeof(stpc))) -+ return EBT_NOMATCH; -+ return ebt_filter_config(info, &stpc); -+ } -+ return EBT_MATCH; -+} -+ -+static int ebt_stp_check(const char *tablename, unsigned int hookmask, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_stp_info *info = (struct ebt_stp_info *)data; -+ int len = EBT_ALIGN(sizeof(struct ebt_stp_info)); -+ uint8_t bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; -+ uint8_t msk[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; -+ -+ if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK || -+ !(info->bitmask & EBT_STP_MASK)) -+ return -EINVAL; -+ if (datalen != len) -+ return -EINVAL; -+ /* Make sure the match only receives stp frames */ -+ if (memcmp(e->destmac, bridge_ula, ETH_ALEN) || -+ memcmp(e->destmsk, msk, ETH_ALEN) || !(e->bitmask & EBT_DESTMAC)) -+ return -EINVAL; -+ -+ return 0; -+} -+ -+static struct ebt_match filter_stp = -+{ -+ .name = EBT_STP_MATCH, -+ .match = ebt_filter_stp, -+ .check = ebt_stp_check, -+ .me = THIS_MODULE, -+}; -+ -+static int __init init(void) -+{ -+ return ebt_register_match(&filter_stp); -+} -+ -+static void __exit fini(void) -+{ -+ ebt_unregister_match(&filter_stp); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_vlan.c src/linux/linux/net/bridge/netfilter/ebt_vlan.c ---- src/linux/linux.stock/net/bridge/netfilter/ebt_vlan.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebt_vlan.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,259 @@ -+/* -+ * Description: EBTables 802.1Q match extension kernelspace module. -+ * Authors: Nick Fedchik -+ * Bart De Schuymer -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static unsigned char debug; -+#define MODULE_VERSION "0.6" -+ -+MODULE_PARM(debug, "0-1b"); -+MODULE_PARM_DESC(debug, "debug=1 is turn on debug messages"); -+MODULE_AUTHOR("Nick Fedchik "); -+MODULE_DESCRIPTION("802.1Q match module (ebtables extension), v" -+ MODULE_VERSION); -+MODULE_LICENSE("GPL"); -+ -+ -+#define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args) -+#define INV_FLAG(_inv_flag_) (info->invflags & _inv_flag_) ? "!" : "" -+#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_ -+#define SET_BITMASK(_BIT_MASK_) info->bitmask |= _BIT_MASK_ -+#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return 1; -+ -+/* -+ * Function description: ebt_filter_vlan() is main engine for -+ * checking passed 802.1Q frame according to -+ * the passed extension parameters (in the *data buffer) -+ * ebt_filter_vlan() is called after successfull check the rule params -+ * by ebt_check_vlan() function. -+ * Parameters: -+ * const struct sk_buff *skb - pointer to passed ethernet frame buffer -+ * const void *data - pointer to passed extension parameters -+ * unsigned int datalen - length of passed *data buffer -+ * const struct net_device *in - -+ * const struct net_device *out - -+ * const struct ebt_counter *c - -+ * Returned values: -+ * 0 - ok (all rule params matched) -+ * 1 - miss (rule params not acceptable to the parsed frame) -+ */ -+static int -+ebt_filter_vlan(const struct sk_buff *skb, -+ const struct net_device *in, -+ const struct net_device *out, -+ const void *data, unsigned int datalen) -+{ -+ struct ebt_vlan_info *info = (struct ebt_vlan_info *) data; /* userspace data */ -+ struct vlan_ethhdr *frame = (struct vlan_ethhdr *) skb->mac.raw; /* Passed tagged frame */ -+ -+ unsigned short TCI; /* Whole TCI, given from parsed frame */ -+ unsigned short id; /* VLAN ID, given from frame TCI */ -+ unsigned char prio; /* user_priority, given from frame TCI */ -+ unsigned short encap; /* VLAN encapsulated Type/Length field, given from orig frame */ -+ -+ /* -+ * Tag Control Information (TCI) consists of the following elements: -+ * - User_priority. The user_priority field is three bits in length, -+ * interpreted as a binary number. -+ * - Canonical Format Indicator (CFI). The Canonical Format Indicator -+ * (CFI) is a single bit flag value. Currently ignored. -+ * - VLAN Identifier (VID). The VID is encoded as -+ * an unsigned binary number. -+ */ -+ TCI = ntohs(frame->h_vlan_TCI); -+ id = TCI & VLAN_VID_MASK; -+ prio = (TCI >> 13) & 0x7; -+ encap = frame->h_vlan_encapsulated_proto; -+ -+ /* -+ * Checking VLAN Identifier (VID) -+ */ -+ if (GET_BITMASK(EBT_VLAN_ID)) { /* Is VLAN ID parsed? */ -+ EXIT_ON_MISMATCH(id, EBT_VLAN_ID); -+ } -+ /* -+ * Checking user_priority -+ */ -+ if (GET_BITMASK(EBT_VLAN_PRIO)) { /* Is VLAN user_priority parsed? */ -+ EXIT_ON_MISMATCH(prio, EBT_VLAN_PRIO); -+ } -+ /* -+ * Checking Encapsulated Proto (Length/Type) field -+ */ -+ if (GET_BITMASK(EBT_VLAN_ENCAP)) { /* Is VLAN Encap parsed? */ -+ EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP); -+ } -+ /* -+ * All possible extension parameters was parsed. -+ * If rule never returned by missmatch, then all ok. -+ */ -+ return 0; -+} -+ -+/* -+ * Function description: ebt_vlan_check() is called when userspace -+ * delivers the table entry to the kernel, -+ * and to check that userspace doesn't give a bad table. -+ * Parameters: -+ * const char *tablename - table name string -+ * unsigned int hooknr - hook number -+ * const struct ebt_entry *e - ebtables entry basic set -+ * const void *data - pointer to passed extension parameters -+ * unsigned int datalen - length of passed *data buffer -+ * Returned values: -+ * 0 - ok (all delivered rule params are correct) -+ * 1 - miss (rule params is out of range, invalid, incompatible, etc.) -+ */ -+static int -+ebt_check_vlan(const char *tablename, -+ unsigned int hooknr, -+ const struct ebt_entry *e, void *data, unsigned int datalen) -+{ -+ struct ebt_vlan_info *info = (struct ebt_vlan_info *) data; -+ -+ /* -+ * Parameters buffer overflow check -+ */ -+ if (datalen != EBT_ALIGN(sizeof(struct ebt_vlan_info))) { -+ DEBUG_MSG -+ ("passed size %d is not eq to ebt_vlan_info (%d)\n", -+ datalen, sizeof(struct ebt_vlan_info)); -+ return -EINVAL; -+ } -+ -+ /* -+ * Is it 802.1Q frame checked? -+ */ -+ if (e->ethproto != __constant_htons(ETH_P_8021Q)) { -+ DEBUG_MSG -+ ("passed entry proto %2.4X is not 802.1Q (8100)\n", -+ (unsigned short) ntohs(e->ethproto)); -+ return -EINVAL; -+ } -+ -+ /* -+ * Check for bitmask range -+ * True if even one bit is out of mask -+ */ -+ if (info->bitmask & ~EBT_VLAN_MASK) { -+ DEBUG_MSG("bitmask %2X is out of mask (%2X)\n", -+ info->bitmask, EBT_VLAN_MASK); -+ return -EINVAL; -+ } -+ -+ /* -+ * Check for inversion flags range -+ */ -+ if (info->invflags & ~EBT_VLAN_MASK) { -+ DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n", -+ info->invflags, EBT_VLAN_MASK); -+ return -EINVAL; -+ } -+ -+ /* -+ * Reserved VLAN ID (VID) values -+ * ----------------------------- -+ * 0 - The null VLAN ID. -+ * 1 - The default Port VID (PVID) -+ * 0x0FFF - Reserved for implementation use. -+ * if_vlan.h: VLAN_GROUP_ARRAY_LEN 4096. -+ */ -+ if (GET_BITMASK(EBT_VLAN_ID)) { /* when vlan-id param was spec-ed */ -+ if (!!info->id) { /* if id!=0 => check vid range */ -+ if (info->id > VLAN_GROUP_ARRAY_LEN) { -+ DEBUG_MSG -+ ("id %d is out of range (1-4096)\n", -+ info->id); -+ return -EINVAL; -+ } -+ /* -+ * Note: This is valid VLAN-tagged frame point. -+ * Any value of user_priority are acceptable, -+ * but should be ignored according to 802.1Q Std. -+ * So we just drop the prio flag. -+ */ -+ info->bitmask &= ~EBT_VLAN_PRIO; -+ } -+ /* -+ * Else, id=0 (null VLAN ID) => user_priority range (any?) -+ */ -+ } -+ -+ if (GET_BITMASK(EBT_VLAN_PRIO)) { -+ if ((unsigned char) info->prio > 7) { -+ DEBUG_MSG -+ ("prio %d is out of range (0-7)\n", -+ info->prio); -+ return -EINVAL; -+ } -+ } -+ /* -+ * Check for encapsulated proto range - it is possible to be -+ * any value for u_short range. -+ * if_ether.h: ETH_ZLEN 60 - Min. octets in frame sans FCS -+ */ -+ if (GET_BITMASK(EBT_VLAN_ENCAP)) { -+ if ((unsigned short) ntohs(info->encap) < ETH_ZLEN) { -+ DEBUG_MSG -+ ("encap frame length %d is less than minimal\n", -+ ntohs(info->encap)); -+ return -EINVAL; -+ } -+ } -+ -+ return 0; -+} -+ -+static struct ebt_match filter_vlan = { -+ {NULL, NULL}, -+ EBT_VLAN_MATCH, -+ ebt_filter_vlan, -+ ebt_check_vlan, -+ NULL, -+ THIS_MODULE -+}; -+ -+/* -+ * Module initialization function. -+ */ -+static int __init init(void) -+{ -+ DEBUG_MSG("ebtables 802.1Q extension module v" -+ MODULE_VERSION "\n"); -+ DEBUG_MSG("module debug=%d\n", !!debug); -+ return ebt_register_match(&filter_vlan); -+} -+ -+/* -+ * Module "finalization" function -+ */ -+static void __exit fini(void) -+{ -+ ebt_unregister_match(&filter_vlan); -+} -+ -+module_init(init); -+module_exit(fini); -+ -+EXPORT_NO_SYMBOLS; -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebtable_broute.c src/linux/linux/net/bridge/netfilter/ebtable_broute.c ---- src/linux/linux.stock/net/bridge/netfilter/ebtable_broute.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebtable_broute.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,79 @@ -+/* -+ * ebtable_broute -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * April, 2002 -+ * -+ * This table lets you choose between routing and bridging for frames -+ * entering on a bridge enslaved nic. This table is traversed before any -+ * other ebtables table. See net/bridge/br_input.c. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+// EBT_ACCEPT means the frame will be bridged -+// EBT_DROP means the frame will be routed -+static struct ebt_entries initial_chain = -+ {0, "BROUTING", 0, EBT_ACCEPT, 0}; -+ -+static struct ebt_replace initial_table = -+{ -+ "broute", 1 << NF_BR_BROUTING, 0, sizeof(struct ebt_entries), -+ { [NF_BR_BROUTING]&initial_chain}, 0, NULL, (char *)&initial_chain -+}; -+ -+static int check(const struct ebt_table_info *info, unsigned int valid_hooks) -+{ -+ if (valid_hooks & ~(1 << NF_BR_BROUTING)) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_table broute_table = -+{ -+ {NULL, NULL}, "broute", &initial_table, 1 << NF_BR_BROUTING, -+ RW_LOCK_UNLOCKED, check, NULL -+}; -+ -+static int ebt_broute(struct sk_buff **pskb) -+{ -+ int ret; -+ -+ ret = ebt_do_table(NF_BR_BROUTING, pskb, (*pskb)->dev, NULL, -+ &broute_table); -+ if (ret == NF_DROP) -+ return 1; // route it -+ return 0; // bridge it -+} -+ -+static int __init init(void) -+{ -+ int ret; -+ -+ ret = ebt_register_table(&broute_table); -+ if (ret < 0) -+ return ret; -+ br_write_lock_bh(BR_NETPROTO_LOCK); -+ // see br_input.c -+ br_should_route_hook = ebt_broute; -+ br_write_unlock_bh(BR_NETPROTO_LOCK); -+ return ret; -+} -+ -+static void __exit fini(void) -+{ -+ br_write_lock_bh(BR_NETPROTO_LOCK); -+ br_should_route_hook = NULL; -+ br_write_unlock_bh(BR_NETPROTO_LOCK); -+ ebt_unregister_table(&broute_table); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebtable_filter.c src/linux/linux/net/bridge/netfilter/ebtable_filter.c ---- src/linux/linux.stock/net/bridge/netfilter/ebtable_filter.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebtable_filter.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,90 @@ -+/* -+ * ebtable_filter -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * April, 2002 -+ * -+ */ -+ -+#include -+#include -+ -+#define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \ -+ (1 << NF_BR_LOCAL_OUT)) -+ -+static struct ebt_entries initial_chains[] = -+{ -+ {0, "INPUT", 0, EBT_ACCEPT, 0}, -+ {0, "FORWARD", 0, EBT_ACCEPT, 0}, -+ {0, "OUTPUT", 0, EBT_ACCEPT, 0} -+}; -+ -+static struct ebt_replace initial_table = -+{ -+ "filter", FILTER_VALID_HOOKS, 0, 3 * sizeof(struct ebt_entries), -+ { [NF_BR_LOCAL_IN]&initial_chains[0], [NF_BR_FORWARD]&initial_chains[1], -+ [NF_BR_LOCAL_OUT]&initial_chains[2] }, 0, NULL, (char *)initial_chains -+}; -+ -+static int check(const struct ebt_table_info *info, unsigned int valid_hooks) -+{ -+ if (valid_hooks & ~FILTER_VALID_HOOKS) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_table frame_filter = -+{ -+ {NULL, NULL}, "filter", &initial_table, FILTER_VALID_HOOKS, -+ RW_LOCK_UNLOCKED, check, NULL -+}; -+ -+static unsigned int -+ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in, -+ const struct net_device *out, int (*okfn)(struct sk_buff *)) -+{ -+ return ebt_do_table(hook, pskb, in, out, &frame_filter); -+} -+ -+static struct nf_hook_ops ebt_ops_filter[] = { -+ { { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_LOCAL_IN, -+ NF_BR_PRI_FILTER_BRIDGED}, -+ { { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_FORWARD, -+ NF_BR_PRI_FILTER_BRIDGED}, -+ { { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_LOCAL_OUT, -+ NF_BR_PRI_FILTER_OTHER} -+}; -+ -+static int __init init(void) -+{ -+ int i, j, ret; -+ -+ ret = ebt_register_table(&frame_filter); -+ if (ret < 0) -+ return ret; -+ for (i = 0; i < sizeof(ebt_ops_filter) / sizeof(ebt_ops_filter[0]); i++) -+ if ((ret = nf_register_hook(&ebt_ops_filter[i])) < 0) -+ goto cleanup; -+ return ret; -+cleanup: -+ for (j = 0; j < i; j++) -+ nf_unregister_hook(&ebt_ops_filter[j]); -+ ebt_unregister_table(&frame_filter); -+ return ret; -+} -+ -+static void __exit fini(void) -+{ -+ int i; -+ -+ for (i = 0; i < sizeof(ebt_ops_filter) / sizeof(ebt_ops_filter[0]); i++) -+ nf_unregister_hook(&ebt_ops_filter[i]); -+ ebt_unregister_table(&frame_filter); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebtable_nat.c src/linux/linux/net/bridge/netfilter/ebtable_nat.c ---- src/linux/linux.stock/net/bridge/netfilter/ebtable_nat.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebtable_nat.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,96 @@ -+/* -+ * ebtable_nat -+ * -+ * Authors: -+ * Bart De Schuymer -+ * -+ * April, 2002 -+ * -+ */ -+ -+#include -+#include -+#define NAT_VALID_HOOKS ((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT) | \ -+ (1 << NF_BR_POST_ROUTING)) -+ -+static struct ebt_entries initial_chains[] = -+{ -+ {0, "PREROUTING", 0, EBT_ACCEPT, 0}, -+ {0, "OUTPUT", 0, EBT_ACCEPT, 0}, -+ {0, "POSTROUTING", 0, EBT_ACCEPT, 0} -+}; -+ -+static struct ebt_replace initial_table = -+{ -+ "nat", NAT_VALID_HOOKS, 0, 3 * sizeof(struct ebt_entries), -+ { [NF_BR_PRE_ROUTING]&initial_chains[0], [NF_BR_LOCAL_OUT]&initial_chains[1], -+ [NF_BR_POST_ROUTING]&initial_chains[2] }, 0, NULL, (char *)initial_chains -+}; -+ -+static int check(const struct ebt_table_info *info, unsigned int valid_hooks) -+{ -+ if (valid_hooks & ~NAT_VALID_HOOKS) -+ return -EINVAL; -+ return 0; -+} -+ -+static struct ebt_table frame_nat = -+{ -+ {NULL, NULL}, "nat", &initial_table, NAT_VALID_HOOKS, -+ RW_LOCK_UNLOCKED, check, NULL -+}; -+ -+static unsigned int -+ebt_nat_dst(unsigned int hook, struct sk_buff **pskb, const struct net_device *in -+ , const struct net_device *out, int (*okfn)(struct sk_buff *)) -+{ -+ return ebt_do_table(hook, pskb, in, out, &frame_nat); -+} -+ -+static unsigned int -+ebt_nat_src(unsigned int hook, struct sk_buff **pskb, const struct net_device *in -+ , const struct net_device *out, int (*okfn)(struct sk_buff *)) -+{ -+ return ebt_do_table(hook, pskb, in, out, &frame_nat); -+} -+ -+static struct nf_hook_ops ebt_ops_nat[] = { -+ { { NULL, NULL }, ebt_nat_dst, PF_BRIDGE, NF_BR_LOCAL_OUT, -+ NF_BR_PRI_NAT_DST_OTHER}, -+ { { NULL, NULL }, ebt_nat_src, PF_BRIDGE, NF_BR_POST_ROUTING, -+ NF_BR_PRI_NAT_SRC}, -+ { { NULL, NULL }, ebt_nat_dst, PF_BRIDGE, NF_BR_PRE_ROUTING, -+ NF_BR_PRI_NAT_DST_BRIDGED}, -+}; -+ -+static int __init init(void) -+{ -+ int i, ret, j; -+ -+ ret = ebt_register_table(&frame_nat); -+ if (ret < 0) -+ return ret; -+ for (i = 0; i < sizeof(ebt_ops_nat) / sizeof(ebt_ops_nat[0]); i++) -+ if ((ret = nf_register_hook(&ebt_ops_nat[i])) < 0) -+ goto cleanup; -+ return ret; -+cleanup: -+ for (j = 0; j < i; j++) -+ nf_unregister_hook(&ebt_ops_nat[j]); -+ ebt_unregister_table(&frame_nat); -+ return ret; -+} -+ -+static void __exit fini(void) -+{ -+ int i; -+ -+ for (i = 0; i < sizeof(ebt_ops_nat) / sizeof(ebt_ops_nat[0]); i++) -+ nf_unregister_hook(&ebt_ops_nat[i]); -+ ebt_unregister_table(&frame_nat); -+} -+ -+module_init(init); -+module_exit(fini); -+EXPORT_NO_SYMBOLS; -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebtables.c src/linux/linux/net/bridge/netfilter/ebtables.c ---- src/linux/linux.stock/net/bridge/netfilter/ebtables.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/bridge/netfilter/ebtables.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,1490 @@ -+/* -+ * ebtables -+ * -+ * Author: -+ * Bart De Schuymer -+ * -+ * ebtables.c,v 2.0, July, 2002 -+ * -+ * This code is stongly inspired on the iptables code which is -+ * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+// used for print_string -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+// needed for logical [in,out]-dev filtering -+#include "../br_private.h" -+ -+// list_named_find -+#define ASSERT_READ_LOCK(x) -+#define ASSERT_WRITE_LOCK(x) -+#include -+ -+#if 0 // use this for remote debugging -+// Copyright (C) 1998 by Ori Pomerantz -+// Print the string to the appropriate tty, the one -+// the current task uses -+static void print_string(char *str) -+{ -+ struct tty_struct *my_tty; -+ -+ /* The tty for the current task */ -+ my_tty = current->tty; -+ if (my_tty != NULL) { -+ (*(my_tty->driver).write)(my_tty, 0, str, strlen(str)); -+ (*(my_tty->driver).write)(my_tty, 0, "\015\012", 2); -+ } -+} -+ -+#define BUGPRINT(args) print_string(args); -+#else -+#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\ -+ "report to author: "format, ## args) -+// #define BUGPRINT(format, args...) -+#endif -+#define MEMPRINT(format, args...) printk("kernel msg: ebtables "\ -+ ": out of memory: "format, ## args) -+// #define MEMPRINT(format, args...) -+ -+ -+ -+// Each cpu has its own set of counters, so there is no need for write_lock in -+// the softirq -+// For reading or updating the counters, the user context needs to -+// get a write_lock -+ -+// The size of each set of counters is altered to get cache alignment -+#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) -+#define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter))) -+#define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \ -+ COUNTER_OFFSET(n) * cpu)) -+ -+ -+ -+static DECLARE_MUTEX(ebt_mutex); -+static LIST_HEAD(ebt_tables); -+static LIST_HEAD(ebt_targets); -+static LIST_HEAD(ebt_matches); -+static LIST_HEAD(ebt_watchers); -+ -+static struct ebt_target ebt_standard_target = -+{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL}; -+ -+static inline int ebt_do_watcher (struct ebt_entry_watcher *w, -+ const struct sk_buff *skb, const struct net_device *in, -+ const struct net_device *out) -+{ -+ w->u.watcher->watcher(skb, in, out, w->data, -+ w->watcher_size); -+ // watchers don't give a verdict -+ return 0; -+} -+ -+static inline int ebt_do_match (struct ebt_entry_match *m, -+ const struct sk_buff *skb, const struct net_device *in, -+ const struct net_device *out) -+{ -+ return m->u.match->match(skb, in, out, m->data, -+ m->match_size); -+} -+ -+static inline int ebt_dev_check(char *entry, const struct net_device *device) -+{ -+ if (*entry == '\0') -+ return 0; -+ if (!device) -+ return 1; -+ return !!strcmp(entry, device->name); -+} -+ -+#define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg)) -+// process standard matches -+static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h, -+ const struct net_device *in, const struct net_device *out) -+{ -+ int verdict, i; -+ -+ if (e->bitmask & EBT_802_3) { -+ if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO)) -+ return 1; -+ } else if (!(e->bitmask & EBT_NOPROTO) && -+ FWINV2(e->ethproto != h->h_proto, EBT_IPROTO)) -+ return 1; -+ -+ if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN)) -+ return 1; -+ if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT)) -+ return 1; -+ if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check( -+ e->logical_in, &in->br_port->br->dev), EBT_ILOGICALIN)) -+ return 1; -+ if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check( -+ e->logical_out, &out->br_port->br->dev), EBT_ILOGICALOUT)) -+ return 1; -+ -+ if (e->bitmask & EBT_SOURCEMAC) { -+ verdict = 0; -+ for (i = 0; i < 6; i++) -+ verdict |= (h->h_source[i] ^ e->sourcemac[i]) & -+ e->sourcemsk[i]; -+ if (FWINV2(verdict != 0, EBT_ISOURCE) ) -+ return 1; -+ } -+ if (e->bitmask & EBT_DESTMAC) { -+ verdict = 0; -+ for (i = 0; i < 6; i++) -+ verdict |= (h->h_dest[i] ^ e->destmac[i]) & -+ e->destmsk[i]; -+ if (FWINV2(verdict != 0, EBT_IDEST) ) -+ return 1; -+ } -+ return 0; -+} -+ -+// Do some firewalling -+unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb, -+ const struct net_device *in, const struct net_device *out, -+ struct ebt_table *table) -+{ -+ int i, nentries; -+ struct ebt_entry *point; -+ struct ebt_counter *counter_base, *cb_base; -+ struct ebt_entry_target *t; -+ int verdict, sp = 0; -+ struct ebt_chainstack *cs; -+ struct ebt_entries *chaininfo; -+ char *base; -+ struct ebt_table_info *private = table->private; -+ -+ read_lock_bh(&table->lock); -+ cb_base = COUNTER_BASE(private->counters, private->nentries, -+ cpu_number_map(smp_processor_id())); -+ if (private->chainstack) -+ cs = private->chainstack[cpu_number_map(smp_processor_id())]; -+ else -+ cs = NULL; -+ chaininfo = private->hook_entry[hook]; -+ nentries = private->hook_entry[hook]->nentries; -+ point = (struct ebt_entry *)(private->hook_entry[hook]->data); -+ counter_base = cb_base + private->hook_entry[hook]->counter_offset; -+ // base for chain jumps -+ base = private->entries; -+ i = 0; -+ while (i < nentries) { -+ if (ebt_basic_match(point, (**pskb).mac.ethernet, in, out)) -+ goto letscontinue; -+ -+ if (EBT_MATCH_ITERATE(point, ebt_do_match, *pskb, in, out) != 0) -+ goto letscontinue; -+ -+ // increase counter -+ (*(counter_base + i)).pcnt++; -+ (*(counter_base + i)).bcnt+=(**pskb).len; -+ -+ // these should only watch: not modify, nor tell us -+ // what to do with the packet -+ EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, in, -+ out); -+ -+ t = (struct ebt_entry_target *) -+ (((char *)point) + point->target_offset); -+ // standard target -+ if (!t->u.target->target) -+ verdict = ((struct ebt_standard_target *)t)->verdict; -+ else -+ verdict = t->u.target->target(pskb, hook, -+ in, out, t->data, t->target_size); -+ if (verdict == EBT_ACCEPT) { -+ read_unlock_bh(&table->lock); -+ return NF_ACCEPT; -+ } -+ if (verdict == EBT_DROP) { -+ read_unlock_bh(&table->lock); -+ return NF_DROP; -+ } -+ if (verdict == EBT_RETURN) { -+letsreturn: -+#ifdef CONFIG_NETFILTER_DEBUG -+ if (sp == 0) { -+ BUGPRINT("RETURN on base chain"); -+ // act like this is EBT_CONTINUE -+ goto letscontinue; -+ } -+#endif -+ sp--; -+ // put all the local variables right -+ i = cs[sp].n; -+ chaininfo = cs[sp].chaininfo; -+ nentries = chaininfo->nentries; -+ point = cs[sp].e; -+ counter_base = cb_base + -+ chaininfo->counter_offset; -+ continue; -+ } -+ if (verdict == EBT_CONTINUE) -+ goto letscontinue; -+#ifdef CONFIG_NETFILTER_DEBUG -+ if (verdict < 0) { -+ BUGPRINT("bogus standard verdict\n"); -+ read_unlock_bh(&table->lock); -+ return NF_DROP; -+ } -+#endif -+ // jump to a udc -+ cs[sp].n = i + 1; -+ cs[sp].chaininfo = chaininfo; -+ cs[sp].e = (struct ebt_entry *) -+ (((char *)point) + point->next_offset); -+ i = 0; -+ chaininfo = (struct ebt_entries *) (base + verdict); -+#ifdef CONFIG_NETFILTER_DEBUG -+ if (chaininfo->distinguisher) { -+ BUGPRINT("jump to non-chain\n"); -+ read_unlock_bh(&table->lock); -+ return NF_DROP; -+ } -+#endif -+ nentries = chaininfo->nentries; -+ point = (struct ebt_entry *)chaininfo->data; -+ counter_base = cb_base + chaininfo->counter_offset; -+ sp++; -+ continue; -+letscontinue: -+ point = (struct ebt_entry *) -+ (((char *)point) + point->next_offset); -+ i++; -+ } -+ -+ // I actually like this :) -+ if (chaininfo->policy == EBT_RETURN) -+ goto letsreturn; -+ if (chaininfo->policy == EBT_ACCEPT) { -+ read_unlock_bh(&table->lock); -+ return NF_ACCEPT; -+ } -+ read_unlock_bh(&table->lock); -+ return NF_DROP; -+} -+ -+// If it succeeds, returns element and locks mutex -+static inline void * -+find_inlist_lock_noload(struct list_head *head, const char *name, int *error, -+ struct semaphore *mutex) -+{ -+ void *ret; -+ -+ *error = down_interruptible(mutex); -+ if (*error != 0) -+ return NULL; -+ -+ ret = list_named_find(head, name); -+ if (!ret) { -+ *error = -ENOENT; -+ up(mutex); -+ } -+ return ret; -+} -+ -+#ifndef CONFIG_KMOD -+#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m)) -+#else -+static void * -+find_inlist_lock(struct list_head *head, const char *name, const char *prefix, -+ int *error, struct semaphore *mutex) -+{ -+ void *ret; -+ -+ ret = find_inlist_lock_noload(head, name, error, mutex); -+ if (!ret) { -+ char modulename[EBT_FUNCTION_MAXNAMELEN + strlen(prefix) + 1]; -+ strcpy(modulename, prefix); -+ strcat(modulename, name); -+ request_module(modulename); -+ ret = find_inlist_lock_noload(head, name, error, mutex); -+ } -+ return ret; -+} -+#endif -+ -+static inline struct ebt_table * -+find_table_lock(const char *name, int *error, struct semaphore *mutex) -+{ -+ return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex); -+} -+ -+static inline struct ebt_match * -+find_match_lock(const char *name, int *error, struct semaphore *mutex) -+{ -+ return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex); -+} -+ -+static inline struct ebt_watcher * -+find_watcher_lock(const char *name, int *error, struct semaphore *mutex) -+{ -+ return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex); -+} -+ -+static inline struct ebt_target * -+find_target_lock(const char *name, int *error, struct semaphore *mutex) -+{ -+ return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex); -+} -+ -+static inline int -+ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, -+ const char *name, unsigned int hookmask, unsigned int *cnt) -+{ -+ struct ebt_match *match; -+ int ret; -+ -+ if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) > -+ ((char *)e) + e->watchers_offset) -+ return -EINVAL; -+ match = find_match_lock(m->u.name, &ret, &ebt_mutex); -+ if (!match) -+ return ret; -+ m->u.match = match; -+ if (match->me) -+ __MOD_INC_USE_COUNT(match->me); -+ up(&ebt_mutex); -+ if (match->check && -+ match->check(name, hookmask, e, m->data, m->match_size) != 0) { -+ BUGPRINT("match->check failed\n"); -+ if (match->me) -+ __MOD_DEC_USE_COUNT(match->me); -+ return -EINVAL; -+ } -+ (*cnt)++; -+ return 0; -+} -+ -+static inline int -+ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, -+ const char *name, unsigned int hookmask, unsigned int *cnt) -+{ -+ struct ebt_watcher *watcher; -+ int ret; -+ -+ if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) > -+ ((char *)e) + e->target_offset) -+ return -EINVAL; -+ watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex); -+ if (!watcher) -+ return ret; -+ w->u.watcher = watcher; -+ if (watcher->me) -+ __MOD_INC_USE_COUNT(watcher->me); -+ up(&ebt_mutex); -+ if (watcher->check && -+ watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) { -+ BUGPRINT("watcher->check failed\n"); -+ if (watcher->me) -+ __MOD_DEC_USE_COUNT(watcher->me); -+ return -EINVAL; -+ } -+ (*cnt)++; -+ return 0; -+} -+ -+// this one is very careful, as it is the first function -+// to parse the userspace data -+static inline int -+ebt_check_entry_size_and_hooks(struct ebt_entry *e, -+ struct ebt_table_info *newinfo, char *base, char *limit, -+ struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt, -+ unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks) -+{ -+ int i; -+ -+ for (i = 0; i < NF_BR_NUMHOOKS; i++) { -+ if ((valid_hooks & (1 << i)) == 0) -+ continue; -+ if ( (char *)hook_entries[i] - base == -+ (char *)e - newinfo->entries) -+ break; -+ } -+ // beginning of a new chain -+ // if i == NF_BR_NUMHOOKS it must be a user defined chain -+ if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) { -+ if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) { -+ // we make userspace set this right, -+ // so there is no misunderstanding -+ BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set " -+ "in distinguisher\n"); -+ return -EINVAL; -+ } -+ // this checks if the previous chain has as many entries -+ // as it said it has -+ if (*n != *cnt) { -+ BUGPRINT("nentries does not equal the nr of entries " -+ "in the chain\n"); -+ return -EINVAL; -+ } -+ // before we look at the struct, be sure it is not too big -+ if ((char *)hook_entries[i] + sizeof(struct ebt_entries) -+ > limit) { -+ BUGPRINT("entries_size too small\n"); -+ return -EINVAL; -+ } -+ if (((struct ebt_entries *)e)->policy != EBT_DROP && -+ ((struct ebt_entries *)e)->policy != EBT_ACCEPT) { -+ // only RETURN from udc -+ if (i != NF_BR_NUMHOOKS || -+ ((struct ebt_entries *)e)->policy != EBT_RETURN) { -+ BUGPRINT("bad policy\n"); -+ return -EINVAL; -+ } -+ } -+ if (i == NF_BR_NUMHOOKS) // it's a user defined chain -+ (*udc_cnt)++; -+ else -+ newinfo->hook_entry[i] = (struct ebt_entries *)e; -+ if (((struct ebt_entries *)e)->counter_offset != *totalcnt) { -+ BUGPRINT("counter_offset != totalcnt"); -+ return -EINVAL; -+ } -+ *n = ((struct ebt_entries *)e)->nentries; -+ *cnt = 0; -+ return 0; -+ } -+ // a plain old entry, heh -+ if (sizeof(struct ebt_entry) > e->watchers_offset || -+ e->watchers_offset > e->target_offset || -+ e->target_offset >= e->next_offset) { -+ BUGPRINT("entry offsets not in right order\n"); -+ return -EINVAL; -+ } -+ // this is not checked anywhere else -+ if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) { -+ BUGPRINT("target size too small\n"); -+ return -EINVAL; -+ } -+ -+ (*cnt)++; -+ (*totalcnt)++; -+ return 0; -+} -+ -+struct ebt_cl_stack -+{ -+ struct ebt_chainstack cs; -+ int from; -+ unsigned int hookmask; -+}; -+ -+// we need these positions to check that the jumps to a different part of the -+// entries is a jump to the beginning of a new chain. -+static inline int -+ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo, -+ struct ebt_entries **hook_entries, unsigned int *n, unsigned int valid_hooks, -+ struct ebt_cl_stack *udc) -+{ -+ int i; -+ -+ // we're only interested in chain starts -+ if (e->bitmask & EBT_ENTRY_OR_ENTRIES) -+ return 0; -+ for (i = 0; i < NF_BR_NUMHOOKS; i++) { -+ if ((valid_hooks & (1 << i)) == 0) -+ continue; -+ if (newinfo->hook_entry[i] == (struct ebt_entries *)e) -+ break; -+ } -+ // only care about udc -+ if (i != NF_BR_NUMHOOKS) -+ return 0; -+ -+ udc[*n].cs.chaininfo = (struct ebt_entries *)e; -+ // these initialisations are depended on later in check_chainloops() -+ udc[*n].cs.n = 0; -+ udc[*n].hookmask = 0; -+ -+ (*n)++; -+ return 0; -+} -+ -+static inline int -+ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i) -+{ -+ if (i && (*i)-- == 0) -+ return 1; -+ if (m->u.match->destroy) -+ m->u.match->destroy(m->data, m->match_size); -+ if (m->u.match->me) -+ __MOD_DEC_USE_COUNT(m->u.match->me); -+ -+ return 0; -+} -+ -+static inline int -+ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i) -+{ -+ if (i && (*i)-- == 0) -+ return 1; -+ if (w->u.watcher->destroy) -+ w->u.watcher->destroy(w->data, w->watcher_size); -+ if (w->u.watcher->me) -+ __MOD_DEC_USE_COUNT(w->u.watcher->me); -+ -+ return 0; -+} -+ -+static inline int -+ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) -+{ -+ struct ebt_entry_target *t; -+ -+ if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) -+ return 0; -+ // we're done -+ if (cnt && (*cnt)-- == 0) -+ return 1; -+ EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL); -+ EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL); -+ t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); -+ if (t->u.target->destroy) -+ t->u.target->destroy(t->data, t->target_size); -+ if (t->u.target->me) -+ __MOD_DEC_USE_COUNT(t->u.target->me); -+ -+ return 0; -+} -+ -+static inline int -+ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, -+ const char *name, unsigned int *cnt, unsigned int valid_hooks, -+ struct ebt_cl_stack *cl_s, unsigned int udc_cnt) -+{ -+ struct ebt_entry_target *t; -+ struct ebt_target *target; -+ unsigned int i, j, hook = 0, hookmask = 0; -+ int ret; -+ -+ // Don't mess with the struct ebt_entries -+ if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) -+ return 0; -+ -+ if (e->bitmask & ~EBT_F_MASK) { -+ BUGPRINT("Unknown flag for bitmask\n"); -+ return -EINVAL; -+ } -+ if (e->invflags & ~EBT_INV_MASK) { -+ BUGPRINT("Unknown flag for inv bitmask\n"); -+ return -EINVAL; -+ } -+ if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) { -+ BUGPRINT("NOPROTO & 802_3 not allowed\n"); -+ return -EINVAL; -+ } -+ // what hook do we belong to? -+ for (i = 0; i < NF_BR_NUMHOOKS; i++) { -+ if ((valid_hooks & (1 << i)) == 0) -+ continue; -+ if ((char *)newinfo->hook_entry[i] < (char *)e) -+ hook = i; -+ else -+ break; -+ } -+ // (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on -+ // a base chain -+ if (i < NF_BR_NUMHOOKS) -+ hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS); -+ else { -+ for (i = 0; i < udc_cnt; i++) -+ if ((char *)(cl_s[i].cs.chaininfo) > (char *)e) -+ break; -+ if (i == 0) -+ hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS); -+ else -+ hookmask = cl_s[i - 1].hookmask; -+ } -+ i = 0; -+ ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i); -+ if (ret != 0) -+ goto cleanup_matches; -+ j = 0; -+ ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j); -+ if (ret != 0) -+ goto cleanup_watchers; -+ t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); -+ target = find_target_lock(t->u.name, &ret, &ebt_mutex); -+ if (!target) -+ goto cleanup_watchers; -+ if (target->me) -+ __MOD_INC_USE_COUNT(target->me); -+ up(&ebt_mutex); -+ -+ t->u.target = target; -+ if (t->u.target == &ebt_standard_target) { -+ if (e->target_offset + sizeof(struct ebt_standard_target) > -+ e->next_offset) { -+ BUGPRINT("Standard target size too big\n"); -+ ret = -EFAULT; -+ goto cleanup_watchers; -+ } -+ if (((struct ebt_standard_target *)t)->verdict < -+ -NUM_STANDARD_TARGETS) { -+ BUGPRINT("Invalid standard target\n"); -+ ret = -EFAULT; -+ goto cleanup_watchers; -+ } -+ } else if ((e->target_offset + t->target_size + -+ sizeof(struct ebt_entry_target) > e->next_offset) || -+ (t->u.target->check && -+ t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){ -+ if (t->u.target->me) -+ __MOD_DEC_USE_COUNT(t->u.target->me); -+ ret = -EFAULT; -+ goto cleanup_watchers; -+ } -+ (*cnt)++; -+ return 0; -+cleanup_watchers: -+ EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j); -+cleanup_matches: -+ EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i); -+ return ret; -+} -+ -+// checks for loops and sets the hook mask for udc -+// the hook mask for udc tells us from which base chains the udc can be -+// accessed. This mask is a parameter to the check() functions of the extensions -+static int check_chainloops(struct ebt_entries *chain, -+ struct ebt_cl_stack *cl_s, unsigned int udc_cnt, -+ unsigned int hooknr, char *base) -+{ -+ int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict; -+ struct ebt_entry *e = (struct ebt_entry *)chain->data; -+ struct ebt_entry_target *t; -+ -+ while (pos < nentries || chain_nr != -1) { -+ // end of udc, go back one 'recursion' step -+ if (pos == nentries) { -+ // put back values of the time when this chain was called -+ e = cl_s[chain_nr].cs.e; -+ if (cl_s[chain_nr].from != -1) -+ nentries = -+ cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries; -+ else -+ nentries = chain->nentries; -+ pos = cl_s[chain_nr].cs.n; -+ // make sure we won't see a loop that isn't one -+ cl_s[chain_nr].cs.n = 0; -+ chain_nr = cl_s[chain_nr].from; -+ if (pos == nentries) -+ continue; -+ } -+ t = (struct ebt_entry_target *) -+ (((char *)e) + e->target_offset); -+ if (strcmp(t->u.name, EBT_STANDARD_TARGET)) -+ goto letscontinue; -+ if (e->target_offset + sizeof(struct ebt_standard_target) > -+ e->next_offset) { -+ BUGPRINT("Standard target size too big\n"); -+ return -1; -+ } -+ verdict = ((struct ebt_standard_target *)t)->verdict; -+ if (verdict >= 0) { // jump to another chain -+ struct ebt_entries *hlp2 = -+ (struct ebt_entries *)(base + verdict); -+ for (i = 0; i < udc_cnt; i++) -+ if (hlp2 == cl_s[i].cs.chaininfo) -+ break; -+ // bad destination or loop -+ if (i == udc_cnt) { -+ BUGPRINT("bad destination\n"); -+ return -1; -+ } -+ if (cl_s[i].cs.n) { -+ BUGPRINT("loop\n"); -+ return -1; -+ } -+ // this can't be 0, so the above test is correct -+ cl_s[i].cs.n = pos + 1; -+ pos = 0; -+ cl_s[i].cs.e = ((void *)e + e->next_offset); -+ e = (struct ebt_entry *)(hlp2->data); -+ nentries = hlp2->nentries; -+ cl_s[i].from = chain_nr; -+ chain_nr = i; -+ // this udc is accessible from the base chain for hooknr -+ cl_s[i].hookmask |= (1 << hooknr); -+ continue; -+ } -+letscontinue: -+ e = (void *)e + e->next_offset; -+ pos++; -+ } -+ return 0; -+} -+ -+// do the parsing of the table/chains/entries/matches/watchers/targets, heh -+static int translate_table(struct ebt_replace *repl, -+ struct ebt_table_info *newinfo) -+{ -+ unsigned int i, j, k, udc_cnt; -+ int ret; -+ struct ebt_cl_stack *cl_s = NULL; // used in the checking for chain loops -+ -+ i = 0; -+ while (i < NF_BR_NUMHOOKS && !(repl->valid_hooks & (1 << i))) -+ i++; -+ if (i == NF_BR_NUMHOOKS) { -+ BUGPRINT("No valid hooks specified\n"); -+ return -EINVAL; -+ } -+ if (repl->hook_entry[i] != (struct ebt_entries *)repl->entries) { -+ BUGPRINT("Chains don't start at beginning\n"); -+ return -EINVAL; -+ } -+ // make sure chains are ordered after each other in same order -+ // as their corresponding hooks -+ for (j = i + 1; j < NF_BR_NUMHOOKS; j++) { -+ if (!(repl->valid_hooks & (1 << j))) -+ continue; -+ if ( repl->hook_entry[j] <= repl->hook_entry[i] ) { -+ BUGPRINT("Hook order must be followed\n"); -+ return -EINVAL; -+ } -+ i = j; -+ } -+ -+ for (i = 0; i < NF_BR_NUMHOOKS; i++) -+ newinfo->hook_entry[i] = NULL; -+ -+ newinfo->entries_size = repl->entries_size; -+ newinfo->nentries = repl->nentries; -+ -+ // do some early checkings and initialize some things -+ i = 0; // holds the expected nr. of entries for the chain -+ j = 0; // holds the up to now counted entries for the chain -+ k = 0; // holds the total nr. of entries, should equal -+ // newinfo->nentries afterwards -+ udc_cnt = 0; // will hold the nr. of user defined chains (udc) -+ ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, -+ ebt_check_entry_size_and_hooks, newinfo, repl->entries, -+ repl->entries + repl->entries_size, repl->hook_entry, &i, &j, &k, -+ &udc_cnt, repl->valid_hooks); -+ -+ if (ret != 0) -+ return ret; -+ -+ if (i != j) { -+ BUGPRINT("nentries does not equal the nr of entries in the " -+ "(last) chain\n"); -+ return -EINVAL; -+ } -+ if (k != newinfo->nentries) { -+ BUGPRINT("Total nentries is wrong\n"); -+ return -EINVAL; -+ } -+ -+ // check if all valid hooks have a chain -+ for (i = 0; i < NF_BR_NUMHOOKS; i++) { -+ if (newinfo->hook_entry[i] == NULL && -+ (repl->valid_hooks & (1 << i))) { -+ BUGPRINT("Valid hook without chain\n"); -+ return -EINVAL; -+ } -+ } -+ -+ // Get the location of the udc, put them in an array -+ // While we're at it, allocate the chainstack -+ if (udc_cnt) { -+ // this will get free'd in do_replace()/ebt_register_table() -+ // if an error occurs -+ newinfo->chainstack = (struct ebt_chainstack **) -+ vmalloc(smp_num_cpus * sizeof(struct ebt_chainstack)); -+ if (!newinfo->chainstack) -+ return -ENOMEM; -+ for (i = 0; i < smp_num_cpus; i++) { -+ newinfo->chainstack[i] = -+ vmalloc(udc_cnt * sizeof(struct ebt_chainstack)); -+ if (!newinfo->chainstack[i]) { -+ while (i) -+ vfree(newinfo->chainstack[--i]); -+ vfree(newinfo->chainstack); -+ newinfo->chainstack = NULL; -+ return -ENOMEM; -+ } -+ } -+ -+ cl_s = (struct ebt_cl_stack *) -+ vmalloc(udc_cnt * sizeof(struct ebt_cl_stack)); -+ if (!cl_s) -+ return -ENOMEM; -+ i = 0; // the i'th udc -+ EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, -+ ebt_get_udc_positions, newinfo, repl->hook_entry, &i, -+ repl->valid_hooks, cl_s); -+ // sanity check -+ if (i != udc_cnt) { -+ BUGPRINT("i != udc_cnt\n"); -+ vfree(cl_s); -+ return -EFAULT; -+ } -+ } -+ -+ // Check for loops -+ for (i = 0; i < NF_BR_NUMHOOKS; i++) -+ if (repl->valid_hooks & (1 << i)) -+ if (check_chainloops(newinfo->hook_entry[i], -+ cl_s, udc_cnt, i, newinfo->entries)) { -+ if (cl_s) -+ vfree(cl_s); -+ return -EINVAL; -+ } -+ -+ // we now know the following (along with E=mc²): -+ // - the nr of entries in each chain is right -+ // - the size of the allocated space is right -+ // - all valid hooks have a corresponding chain -+ // - there are no loops -+ // - wrong data can still be on the level of a single entry -+ // - could be there are jumps to places that are not the -+ // beginning of a chain. This can only occur in chains that -+ // are not accessible from any base chains, so we don't care. -+ -+ // used to know what we need to clean up if something goes wrong -+ i = 0; -+ ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, -+ ebt_check_entry, newinfo, repl->name, &i, repl->valid_hooks, -+ cl_s, udc_cnt); -+ if (ret != 0) { -+ EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, -+ ebt_cleanup_entry, &i); -+ } -+ if (cl_s) -+ vfree(cl_s); -+ return ret; -+} -+ -+// called under write_lock -+static void get_counters(struct ebt_counter *oldcounters, -+ struct ebt_counter *counters, unsigned int nentries) -+{ -+ int i, cpu; -+ struct ebt_counter *counter_base; -+ -+ // counters of cpu 0 -+ memcpy(counters, oldcounters, -+ sizeof(struct ebt_counter) * nentries); -+ // add other counters to those of cpu 0 -+ for (cpu = 1; cpu < smp_num_cpus; cpu++) { -+ counter_base = COUNTER_BASE(oldcounters, nentries, cpu); -+ for (i = 0; i < nentries; i++) { -+ counters[i].pcnt += counter_base[i].pcnt; -+ counters[i].bcnt += counter_base[i].bcnt; -+ } -+ } -+} -+ -+// replace the table -+static int do_replace(void *user, unsigned int len) -+{ -+ int ret, i, countersize; -+ struct ebt_table_info *newinfo; -+ struct ebt_replace tmp; -+ struct ebt_table *t; -+ struct ebt_counter *counterstmp = NULL; -+ // used to be able to unlock earlier -+ struct ebt_table_info *table; -+ -+ if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) -+ return -EFAULT; -+ -+ if (len != sizeof(tmp) + tmp.entries_size) { -+ BUGPRINT("Wrong len argument\n"); -+ return -EINVAL; -+ } -+ -+ if (tmp.entries_size == 0) { -+ BUGPRINT("Entries_size never zero\n"); -+ return -EINVAL; -+ } -+ countersize = COUNTER_OFFSET(tmp.nentries) * smp_num_cpus; -+ newinfo = (struct ebt_table_info *) -+ vmalloc(sizeof(struct ebt_table_info) + countersize); -+ if (!newinfo) -+ return -ENOMEM; -+ -+ if (countersize) -+ memset(newinfo->counters, 0, countersize); -+ -+ newinfo->entries = (char *)vmalloc(tmp.entries_size); -+ if (!newinfo->entries) { -+ ret = -ENOMEM; -+ goto free_newinfo; -+ } -+ if (copy_from_user( -+ newinfo->entries, tmp.entries, tmp.entries_size) != 0) { -+ BUGPRINT("Couldn't copy entries from userspace\n"); -+ ret = -EFAULT; -+ goto free_entries; -+ } -+ -+ // the user wants counters back -+ // the check on the size is done later, when we have the lock -+ if (tmp.num_counters) { -+ counterstmp = (struct ebt_counter *) -+ vmalloc(tmp.num_counters * sizeof(struct ebt_counter)); -+ if (!counterstmp) { -+ ret = -ENOMEM; -+ goto free_entries; -+ } -+ } -+ else -+ counterstmp = NULL; -+ -+ // this can get initialized by translate_table() -+ newinfo->chainstack = NULL; -+ ret = translate_table(&tmp, newinfo); -+ -+ if (ret != 0) -+ goto free_counterstmp; -+ -+ t = find_table_lock(tmp.name, &ret, &ebt_mutex); -+ if (!t) -+ goto free_iterate; -+ -+ // the table doesn't like it -+ if (t->check && (ret = t->check(newinfo, tmp.valid_hooks))) -+ goto free_unlock; -+ -+ if (tmp.num_counters && tmp.num_counters != t->private->nentries) { -+ BUGPRINT("Wrong nr. of counters requested\n"); -+ ret = -EINVAL; -+ goto free_unlock; -+ } -+ -+ // we have the mutex lock, so no danger in reading this pointer -+ table = t->private; -+ // we need an atomic snapshot of the counters -+ write_lock_bh(&t->lock); -+ if (tmp.num_counters) -+ get_counters(t->private->counters, counterstmp, -+ t->private->nentries); -+ -+ t->private = newinfo; -+ write_unlock_bh(&t->lock); -+ up(&ebt_mutex); -+ // So, a user can change the chains while having messed up her counter -+ // allocation. Only reason why this is done is because this way the lock -+ // is held only once, while this doesn't bring the kernel into a -+ // dangerous state. -+ if (tmp.num_counters && -+ copy_to_user(tmp.counters, counterstmp, -+ tmp.num_counters * sizeof(struct ebt_counter))) { -+ BUGPRINT("Couldn't copy counters to userspace\n"); -+ ret = -EFAULT; -+ } -+ else -+ ret = 0; -+ -+ // decrease module count and free resources -+ EBT_ENTRY_ITERATE(table->entries, table->entries_size, -+ ebt_cleanup_entry, NULL); -+ -+ vfree(table->entries); -+ if (table->chainstack) { -+ for (i = 0; i < smp_num_cpus; i++) -+ vfree(table->chainstack[i]); -+ vfree(table->chainstack); -+ } -+ vfree(table); -+ -+ if (counterstmp) -+ vfree(counterstmp); -+ return ret; -+ -+free_unlock: -+ up(&ebt_mutex); -+free_iterate: -+ EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, -+ ebt_cleanup_entry, NULL); -+free_counterstmp: -+ if (counterstmp) -+ vfree(counterstmp); -+ // can be initialized in translate_table() -+ if (newinfo->chainstack) { -+ for (i = 0; i < smp_num_cpus; i++) -+ vfree(newinfo->chainstack[i]); -+ vfree(newinfo->chainstack); -+ } -+free_entries: -+ if (newinfo->entries) -+ vfree(newinfo->entries); -+free_newinfo: -+ if (newinfo) -+ vfree(newinfo); -+ return ret; -+} -+ -+int ebt_register_target(struct ebt_target *target) -+{ -+ int ret; -+ -+ ret = down_interruptible(&ebt_mutex); -+ if (ret != 0) -+ return ret; -+ if (!list_named_insert(&ebt_targets, target)) { -+ up(&ebt_mutex); -+ return -EEXIST; -+ } -+ up(&ebt_mutex); -+ MOD_INC_USE_COUNT; -+ -+ return 0; -+} -+ -+void ebt_unregister_target(struct ebt_target *target) -+{ -+ down(&ebt_mutex); -+ LIST_DELETE(&ebt_targets, target); -+ up(&ebt_mutex); -+ MOD_DEC_USE_COUNT; -+} -+ -+int ebt_register_match(struct ebt_match *match) -+{ -+ int ret; -+ -+ ret = down_interruptible(&ebt_mutex); -+ if (ret != 0) -+ return ret; -+ if (!list_named_insert(&ebt_matches, match)) { -+ up(&ebt_mutex); -+ return -EEXIST; -+ } -+ up(&ebt_mutex); -+ MOD_INC_USE_COUNT; -+ -+ return 0; -+} -+ -+void ebt_unregister_match(struct ebt_match *match) -+{ -+ down(&ebt_mutex); -+ LIST_DELETE(&ebt_matches, match); -+ up(&ebt_mutex); -+ MOD_DEC_USE_COUNT; -+} -+ -+int ebt_register_watcher(struct ebt_watcher *watcher) -+{ -+ int ret; -+ -+ ret = down_interruptible(&ebt_mutex); -+ if (ret != 0) -+ return ret; -+ if (!list_named_insert(&ebt_watchers, watcher)) { -+ up(&ebt_mutex); -+ return -EEXIST; -+ } -+ up(&ebt_mutex); -+ MOD_INC_USE_COUNT; -+ -+ return 0; -+} -+ -+void ebt_unregister_watcher(struct ebt_watcher *watcher) -+{ -+ down(&ebt_mutex); -+ LIST_DELETE(&ebt_watchers, watcher); -+ up(&ebt_mutex); -+ MOD_DEC_USE_COUNT; -+} -+ -+int ebt_register_table(struct ebt_table *table) -+{ -+ struct ebt_table_info *newinfo; -+ int ret, i, countersize; -+ -+ if (!table || !table->table ||!table->table->entries || -+ table->table->entries_size == 0 || -+ table->table->counters || table->private) { -+ BUGPRINT("Bad table data for ebt_register_table!!!\n"); -+ return -EINVAL; -+ } -+ -+ countersize = COUNTER_OFFSET(table->table->nentries) * smp_num_cpus; -+ newinfo = (struct ebt_table_info *) -+ vmalloc(sizeof(struct ebt_table_info) + countersize); -+ ret = -ENOMEM; -+ if (!newinfo) -+ return -ENOMEM; -+ -+ newinfo->entries = (char *)vmalloc(table->table->entries_size); -+ if (!(newinfo->entries)) -+ goto free_newinfo; -+ -+ memcpy(newinfo->entries, table->table->entries, -+ table->table->entries_size); -+ -+ if (countersize) -+ memset(newinfo->counters, 0, countersize); -+ -+ // fill in newinfo and parse the entries -+ newinfo->chainstack = NULL; -+ ret = translate_table(table->table, newinfo); -+ if (ret != 0) { -+ BUGPRINT("Translate_table failed\n"); -+ goto free_chainstack; -+ } -+ -+ if (table->check && table->check(newinfo, table->valid_hooks)) { -+ BUGPRINT("The table doesn't like its own initial data, lol\n"); -+ return -EINVAL; -+ } -+ -+ table->private = newinfo; -+ table->lock = RW_LOCK_UNLOCKED; -+ ret = down_interruptible(&ebt_mutex); -+ if (ret != 0) -+ goto free_chainstack; -+ -+ if (list_named_find(&ebt_tables, table->name)) { -+ ret = -EEXIST; -+ BUGPRINT("Table name already exists\n"); -+ goto free_unlock; -+ } -+ -+ list_prepend(&ebt_tables, table); -+ up(&ebt_mutex); -+ MOD_INC_USE_COUNT; -+ return 0; -+free_unlock: -+ up(&ebt_mutex); -+free_chainstack: -+ if (newinfo->chainstack) { -+ for (i = 0; i < smp_num_cpus; i++) -+ vfree(newinfo->chainstack[i]); -+ vfree(newinfo->chainstack); -+ } -+ vfree(newinfo->entries); -+free_newinfo: -+ vfree(newinfo); -+ return ret; -+} -+ -+void ebt_unregister_table(struct ebt_table *table) -+{ -+ int i; -+ -+ if (!table) { -+ BUGPRINT("Request to unregister NULL table!!!\n"); -+ return; -+ } -+ down(&ebt_mutex); -+ LIST_DELETE(&ebt_tables, table); -+ up(&ebt_mutex); -+ EBT_ENTRY_ITERATE(table->private->entries, -+ table->private->entries_size, ebt_cleanup_entry, NULL); -+ if (table->private->entries) -+ vfree(table->private->entries); -+ if (table->private->chainstack) { -+ for (i = 0; i < smp_num_cpus; i++) -+ vfree(table->private->chainstack[i]); -+ vfree(table->private->chainstack); -+ } -+ vfree(table->private); -+ MOD_DEC_USE_COUNT; -+} -+ -+// userspace just supplied us with counters -+static int update_counters(void *user, unsigned int len) -+{ -+ int i, ret; -+ struct ebt_counter *tmp; -+ struct ebt_replace hlp; -+ struct ebt_table *t; -+ -+ if (copy_from_user(&hlp, user, sizeof(hlp))) -+ return -EFAULT; -+ -+ if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter)) -+ return -EINVAL; -+ if (hlp.num_counters == 0) -+ return -EINVAL; -+ -+ if ( !(tmp = (struct ebt_counter *) -+ vmalloc(hlp.num_counters * sizeof(struct ebt_counter))) ){ -+ MEMPRINT("Update_counters && nomemory\n"); -+ return -ENOMEM; -+ } -+ -+ t = find_table_lock(hlp.name, &ret, &ebt_mutex); -+ if (!t) -+ goto free_tmp; -+ -+ if (hlp.num_counters != t->private->nentries) { -+ BUGPRINT("Wrong nr of counters\n"); -+ ret = -EINVAL; -+ goto unlock_mutex; -+ } -+ -+ if ( copy_from_user(tmp, hlp.counters, -+ hlp.num_counters * sizeof(struct ebt_counter)) ) { -+ BUGPRINT("Updata_counters && !cfu\n"); -+ ret = -EFAULT; -+ goto unlock_mutex; -+ } -+ -+ // we want an atomic add of the counters -+ write_lock_bh(&t->lock); -+ -+ // we add to the counters of the first cpu -+ for (i = 0; i < hlp.num_counters; i++) { -+ t->private->counters[i].pcnt += tmp[i].pcnt; -+ t->private->counters[i].bcnt += tmp[i].bcnt; -+ } -+ -+ write_unlock_bh(&t->lock); -+ ret = 0; -+unlock_mutex: -+ up(&ebt_mutex); -+free_tmp: -+ vfree(tmp); -+ return ret; -+} -+ -+static inline int ebt_make_matchname(struct ebt_entry_match *m, -+ char *base, char *ubase) -+{ -+ char *hlp = ubase - base + (char *)m; -+ if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN)) -+ return -EFAULT; -+ return 0; -+} -+ -+static inline int ebt_make_watchername(struct ebt_entry_watcher *w, -+ char *base, char *ubase) -+{ -+ char *hlp = ubase - base + (char *)w; -+ if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN)) -+ return -EFAULT; -+ return 0; -+} -+ -+static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase) -+{ -+ int ret; -+ char *hlp; -+ struct ebt_entry_target *t; -+ -+ if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) -+ return 0; -+ -+ hlp = ubase - base + (char *)e + e->target_offset; -+ t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); -+ -+ ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase); -+ if (ret != 0) -+ return ret; -+ ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase); -+ if (ret != 0) -+ return ret; -+ if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN)) -+ return -EFAULT; -+ return 0; -+} -+ -+// called with ebt_mutex down -+static int copy_everything_to_user(struct ebt_table *t, void *user, -+ int *len, int cmd) -+{ -+ struct ebt_replace tmp; -+ struct ebt_counter *counterstmp, *oldcounters; -+ unsigned int entries_size, nentries; -+ char *entries; -+ -+ if (cmd == EBT_SO_GET_ENTRIES) { -+ entries_size = t->private->entries_size; -+ nentries = t->private->nentries; -+ entries = t->private->entries; -+ oldcounters = t->private->counters; -+ } else { -+ entries_size = t->table->entries_size; -+ nentries = t->table->nentries; -+ entries = t->table->entries; -+ oldcounters = t->table->counters; -+ } -+ -+ if (copy_from_user(&tmp, user, sizeof(tmp))) { -+ BUGPRINT("Cfu didn't work\n"); -+ return -EFAULT; -+ } -+ -+ if (*len != sizeof(struct ebt_replace) + entries_size + -+ (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) { -+ BUGPRINT("Wrong size\n"); -+ return -EINVAL; -+ } -+ -+ if (tmp.nentries != nentries) { -+ BUGPRINT("Nentries wrong\n"); -+ return -EINVAL; -+ } -+ -+ if (tmp.entries_size != entries_size) { -+ BUGPRINT("Wrong size\n"); -+ return -EINVAL; -+ } -+ -+ // userspace might not need the counters -+ if (tmp.num_counters) { -+ if (tmp.num_counters != nentries) { -+ BUGPRINT("Num_counters wrong\n"); -+ return -EINVAL; -+ } -+ counterstmp = (struct ebt_counter *) -+ vmalloc(nentries * sizeof(struct ebt_counter)); -+ if (!counterstmp) { -+ MEMPRINT("Couldn't copy counters, out of memory\n"); -+ return -ENOMEM; -+ } -+ write_lock_bh(&t->lock); -+ get_counters(oldcounters, counterstmp, nentries); -+ write_unlock_bh(&t->lock); -+ -+ if (copy_to_user(tmp.counters, counterstmp, -+ nentries * sizeof(struct ebt_counter))) { -+ BUGPRINT("Couldn't copy counters to userspace\n"); -+ vfree(counterstmp); -+ return -EFAULT; -+ } -+ vfree(counterstmp); -+ } -+ -+ if (copy_to_user(tmp.entries, entries, entries_size)) { -+ BUGPRINT("Couldn't copy entries to userspace\n"); -+ return -EFAULT; -+ } -+ // set the match/watcher/target names right -+ return EBT_ENTRY_ITERATE(entries, entries_size, -+ ebt_make_names, entries, tmp.entries); -+} -+ -+static int do_ebt_set_ctl(struct sock *sk, -+ int cmd, void *user, unsigned int len) -+{ -+ int ret; -+ -+ switch(cmd) { -+ case EBT_SO_SET_ENTRIES: -+ ret = do_replace(user, len); -+ break; -+ case EBT_SO_SET_COUNTERS: -+ ret = update_counters(user, len); -+ break; -+ default: -+ ret = -EINVAL; -+ } -+ return ret; -+} -+ -+static int do_ebt_get_ctl(struct sock *sk, int cmd, void *user, int *len) -+{ -+ int ret; -+ struct ebt_replace tmp; -+ struct ebt_table *t; -+ -+ if (copy_from_user(&tmp, user, sizeof(tmp))) -+ return -EFAULT; -+ -+ t = find_table_lock(tmp.name, &ret, &ebt_mutex); -+ if (!t) -+ return ret; -+ -+ switch(cmd) { -+ case EBT_SO_GET_INFO: -+ case EBT_SO_GET_INIT_INFO: -+ if (*len != sizeof(struct ebt_replace)){ -+ ret = -EINVAL; -+ up(&ebt_mutex); -+ break; -+ } -+ if (cmd == EBT_SO_GET_INFO) { -+ tmp.nentries = t->private->nentries; -+ tmp.entries_size = t->private->entries_size; -+ tmp.valid_hooks = t->valid_hooks; -+ } else { -+ tmp.nentries = t->table->nentries; -+ tmp.entries_size = t->table->entries_size; -+ tmp.valid_hooks = t->table->valid_hooks; -+ } -+ up(&ebt_mutex); -+ if (copy_to_user(user, &tmp, *len) != 0){ -+ BUGPRINT("c2u Didn't work\n"); -+ ret = -EFAULT; -+ break; -+ } -+ ret = 0; -+ break; -+ -+ case EBT_SO_GET_ENTRIES: -+ case EBT_SO_GET_INIT_ENTRIES: -+ ret = copy_everything_to_user(t, user, len, cmd); -+ up(&ebt_mutex); -+ break; -+ -+ default: -+ up(&ebt_mutex); -+ ret = -EINVAL; -+ } -+ -+ return ret; -+} -+ -+static struct nf_sockopt_ops ebt_sockopts = -+{ { NULL, NULL }, PF_INET, EBT_BASE_CTL, EBT_SO_SET_MAX + 1, do_ebt_set_ctl, -+ EBT_BASE_CTL, EBT_SO_GET_MAX + 1, do_ebt_get_ctl, 0, NULL -+}; -+ -+static int __init init(void) -+{ -+ int ret; -+ -+ down(&ebt_mutex); -+ list_named_insert(&ebt_targets, &ebt_standard_target); -+ up(&ebt_mutex); -+ if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) -+ return ret; -+ -+ printk(KERN_NOTICE "Ebtables v2.0 registered\n"); -+ return 0; -+} -+ -+static void __exit fini(void) -+{ -+ nf_unregister_sockopt(&ebt_sockopts); -+ printk(KERN_NOTICE "Ebtables v2.0 unregistered\n"); -+} -+ -+EXPORT_SYMBOL(ebt_register_table); -+EXPORT_SYMBOL(ebt_unregister_table); -+EXPORT_SYMBOL(ebt_register_match); -+EXPORT_SYMBOL(ebt_unregister_match); -+EXPORT_SYMBOL(ebt_register_watcher); -+EXPORT_SYMBOL(ebt_unregister_watcher); -+EXPORT_SYMBOL(ebt_register_target); -+EXPORT_SYMBOL(ebt_unregister_target); -+EXPORT_SYMBOL(ebt_do_table); -+module_init(init); -+module_exit(fini); -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.stock/net/core/dev.c src/linux/linux/net/core/dev.c ---- src/linux/linux.stock/net/core/dev.c 2003-10-14 04:02:55.000000000 -0400 -+++ src/linux/linux/net/core/dev.c 2004-07-10 23:46:39.000000000 -0400 -@@ -1393,7 +1393,7 @@ - - - #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) --void (*br_handle_frame_hook)(struct sk_buff *skb) = NULL; -+int (*br_handle_frame_hook)(struct sk_buff *skb) = NULL; - #endif - - static __inline__ int handle_bridge(struct sk_buff *skb, -@@ -1410,7 +1410,6 @@ - } - } - -- br_handle_frame_hook(skb); - return ret; - } - -@@ -1470,7 +1469,12 @@ - #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) - if (skb->dev->br_port != NULL && - br_handle_frame_hook != NULL) { -- return handle_bridge(skb, pt_prev); -+ int ret; -+ -+ ret = handle_bridge(skb, pt_prev); -+ if (br_handle_frame_hook(skb) == 0) -+ return ret; -+ pt_prev = NULL; - } - #endif - -diff -Nurb src/linux/linux.stock/net/core/netfilter.c src/linux/linux/net/core/netfilter.c ---- src/linux/linux.stock/net/core/netfilter.c 2004-07-10 23:29:56.000000000 -0400 -+++ src/linux/linux/net/core/netfilter.c 2004-07-10 23:46:39.000000000 -0400 -@@ -344,10 +344,15 @@ - const struct net_device *indev, - const struct net_device *outdev, - struct list_head **i, -- int (*okfn)(struct sk_buff *)) -+ int (*okfn)(struct sk_buff *), -+ int hook_thresh) - { - for (*i = (*i)->next; *i != head; *i = (*i)->next) { - struct nf_hook_ops *elem = (struct nf_hook_ops *)*i; -+ -+ if (hook_thresh > elem->priority) -+ continue; -+ - switch (elem->hook(hook, skb, indev, outdev, okfn)) { - case NF_QUEUE: - return NF_QUEUE; -@@ -415,6 +420,10 @@ - { - int status; - struct nf_info *info; -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ struct net_device *physindev = NULL; -+ struct net_device *physoutdev = NULL; -+#endif - - if (!queue_handler[pf].outfn) { - kfree_skb(skb); -@@ -437,11 +446,24 @@ - if (indev) dev_hold(indev); - if (outdev) dev_hold(outdev); - -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ if (skb->nf_bridge) { -+ physindev = skb->nf_bridge->physindev; -+ if (physindev) dev_hold(physindev); -+ physoutdev = skb->nf_bridge->physoutdev; -+ if (physoutdev) dev_hold(physoutdev); -+ } -+#endif -+ - status = queue_handler[pf].outfn(skb, info, queue_handler[pf].data); - if (status < 0) { - /* James M doesn't say fuck enough. */ - if (indev) dev_put(indev); - if (outdev) dev_put(outdev); -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ if (physindev) dev_put(physindev); -+ if (physoutdev) dev_put(physoutdev); -+#endif - kfree(info); - kfree_skb(skb); - return; -@@ -451,7 +473,8 @@ - int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, - struct net_device *indev, - struct net_device *outdev, -- int (*okfn)(struct sk_buff *)) -+ int (*okfn)(struct sk_buff *), -+ int hook_thresh) - { - struct list_head *elem; - unsigned int verdict; -@@ -483,7 +506,7 @@ - - elem = &nf_hooks[pf][hook]; - verdict = nf_iterate(&nf_hooks[pf][hook], &skb, hook, indev, -- outdev, &elem, okfn); -+ outdev, &elem, okfn, hook_thresh); - if (verdict == NF_QUEUE) { - NFDEBUG("nf_hook: Verdict = QUEUE.\n"); - nf_queue(skb, elem, pf, hook, indev, outdev, okfn); -@@ -512,6 +535,14 @@ - - /* We don't have BR_NETPROTO_LOCK here */ - br_read_lock_bh(BR_NETPROTO_LOCK); -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ if (skb->nf_bridge) { -+ if (skb->nf_bridge->physindev) -+ dev_put(skb->nf_bridge->physindev); -+ if (skb->nf_bridge->physoutdev) -+ dev_put(skb->nf_bridge->physoutdev); -+ } -+#endif - for (i = nf_hooks[info->pf][info->hook].next; i != elem; i = i->next) { - if (i == &nf_hooks[info->pf][info->hook]) { - /* The module which sent it to userspace is gone. */ -@@ -532,7 +563,7 @@ - verdict = nf_iterate(&nf_hooks[info->pf][info->hook], - &skb, info->hook, - info->indev, info->outdev, &elem, -- info->okfn); -+ info->okfn, INT_MIN); - } - - switch (verdict) { -diff -Nurb src/linux/linux.stock/net/core/skbuff.c src/linux/linux/net/core/skbuff.c ---- src/linux/linux.stock/net/core/skbuff.c 2003-10-14 04:09:32.000000000 -0400 -+++ src/linux/linux/net/core/skbuff.c 2004-07-10 23:46:39.000000000 -0400 -@@ -244,6 +244,9 @@ - #ifdef CONFIG_NETFILTER_DEBUG - skb->nf_debug = 0; - #endif -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ skb->nf_bridge = NULL; -+#endif - #endif - #ifdef CONFIG_NET_SCHED - skb->tc_index = 0; -@@ -324,6 +327,9 @@ - } - #ifdef CONFIG_NETFILTER - nf_conntrack_put(skb->nfct); -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ nf_bridge_put(skb->nf_bridge); -+#endif - #endif - skb_headerinit(skb, NULL, 0); /* clean state */ - kfree_skbmem(skb); -@@ -390,6 +396,9 @@ - #ifdef CONFIG_NETFILTER_DEBUG - C(nf_debug); - #endif -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ C(nf_bridge); -+#endif - #endif /*CONFIG_NETFILTER*/ - #if defined(CONFIG_HIPPI) - C(private); -@@ -402,6 +411,9 @@ - skb->cloned = 1; - #ifdef CONFIG_NETFILTER - nf_conntrack_get(skb->nfct); -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ nf_bridge_get(skb->nf_bridge); -+#endif - #endif - return n; - } -@@ -436,6 +448,10 @@ - #ifdef CONFIG_NETFILTER_DEBUG - new->nf_debug=old->nf_debug; - #endif -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ new->nf_bridge=old->nf_bridge; -+ nf_bridge_get(new->nf_bridge); -+#endif - #endif - #ifdef CONFIG_NET_SCHED - new->tc_index = old->tc_index; -@@ -722,8 +738,8 @@ - /* Set the tail pointer and length */ - skb_put(n,skb->len); - -- /* Copy the data only. */ -- if (skb_copy_bits(skb, 0, n->data, skb->len)) -+ /* Copy the linear data and header. */ -+ if (skb_copy_bits(skb, -newheadroom, n->head, newheadroom + skb->len)) - BUG(); - - copy_skb_header(n, skb); -diff -Nurb src/linux/linux.stock/net/ipv4/ip_output.c src/linux/linux/net/ipv4/ip_output.c ---- src/linux/linux.stock/net/ipv4/ip_output.c 2003-10-14 04:09:33.000000000 -0400 -+++ src/linux/linux/net/ipv4/ip_output.c 2004-07-10 23:46:39.000000000 -0400 -@@ -879,6 +879,10 @@ - /* Connection association is same as pre-frag packet */ - skb2->nfct = skb->nfct; - nf_conntrack_get(skb2->nfct); -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ skb2->nf_bridge = skb->nf_bridge; -+ nf_bridge_get(skb2->nf_bridge); -+#endif - #ifdef CONFIG_NETFILTER_DEBUG - skb2->nf_debug = skb->nf_debug; - #endif -diff -Nurb src/linux/linux.stock/net/ipv4/netfilter/Config.in src/linux/linux/net/ipv4/netfilter/Config.in ---- src/linux/linux.stock/net/ipv4/netfilter/Config.in 2004-07-10 23:30:19.000000000 -0400 -+++ src/linux/linux/net/ipv4/netfilter/Config.in 2004-07-10 23:46:39.000000000 -0400 -@@ -83,6 +83,9 @@ - dep_tristate ' String match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_STRING $CONFIG_IP_NF_IPTABLES - dep_tristate ' Owner match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_OWNER $CONFIG_IP_NF_IPTABLES - fi -+ if [ "$CONFIG_BRIDGE" != "n" ]; then -+ dep_tristate ' Physdev match support' CONFIG_IP_NF_MATCH_PHYSDEV $CONFIG_IP_NF_IPTABLES -+ fi - # The targets - dep_tristate ' Packet filtering' CONFIG_IP_NF_FILTER $CONFIG_IP_NF_IPTABLES - if [ "$CONFIG_IP_NF_FILTER" != "n" ]; then -diff -Nurb src/linux/linux.stock/net/ipv4/netfilter/Makefile src/linux/linux/net/ipv4/netfilter/Makefile ---- src/linux/linux.stock/net/ipv4/netfilter/Makefile 2004-07-10 23:30:19.000000000 -0400 -+++ src/linux/linux/net/ipv4/netfilter/Makefile 2004-07-10 23:46:39.000000000 -0400 -@@ -149,6 +149,8 @@ - obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o - obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o - -+obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o -+ - # targets - obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o - obj-$(CONFIG_IP_NF_TARGET_MIRROR) += ipt_MIRROR.o -diff -Nurb src/linux/linux.stock/net/ipv4/netfilter/ip_tables.c src/linux/linux/net/ipv4/netfilter/ip_tables.c ---- src/linux/linux.stock/net/ipv4/netfilter/ip_tables.c 2004-07-10 23:29:53.000000000 -0400 -+++ src/linux/linux/net/ipv4/netfilter/ip_tables.c 2004-07-10 23:46:39.000000000 -0400 -@@ -121,12 +121,19 @@ - static inline int - ip_packet_match(const struct iphdr *ip, - const char *indev, -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ const char *physindev, -+#endif - const char *outdev, -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ const char *physoutdev, -+#endif - const struct ipt_ip *ipinfo, - int isfrag) - { - size_t i; - unsigned long ret; -+ unsigned long ret2 = 1; - - #define FWINV(bool,invflg) ((bool) ^ !!(ipinfo->invflags & invflg)) - -@@ -156,7 +163,15 @@ - & ((const unsigned long *)ipinfo->iniface_mask)[i]; - } - -- if (FWINV(ret != 0, IPT_INV_VIA_IN)) { -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ for (i = 0, ret2 = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { -+ ret2 |= (((const unsigned long *)physindev)[i] -+ ^ ((const unsigned long *)ipinfo->iniface)[i]) -+ & ((const unsigned long *)ipinfo->iniface_mask)[i]; -+ } -+#endif -+ -+ if (FWINV(ret != 0 && ret2 != 0, IPT_INV_VIA_IN)) { - dprintf("VIA in mismatch (%s vs %s).%s\n", - indev, ipinfo->iniface, - ipinfo->invflags&IPT_INV_VIA_IN ?" (INV)":""); -@@ -169,7 +184,15 @@ - & ((const unsigned long *)ipinfo->outiface_mask)[i]; - } - -- if (FWINV(ret != 0, IPT_INV_VIA_OUT)) { -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ for (i = 0, ret2 = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { -+ ret2 |= (((const unsigned long *)physoutdev)[i] -+ ^ ((const unsigned long *)ipinfo->outiface)[i]) -+ & ((const unsigned long *)ipinfo->outiface_mask)[i]; -+ } -+#endif -+ -+ if (FWINV(ret != 0 && ret2 != 0, IPT_INV_VIA_OUT)) { - dprintf("VIA out mismatch (%s vs %s).%s\n", - outdev, ipinfo->outiface, - ipinfo->invflags&IPT_INV_VIA_OUT ?" (INV)":""); -@@ -272,6 +295,9 @@ - /* Initializing verdict to NF_DROP keeps gcc happy. */ - unsigned int verdict = NF_DROP; - const char *indev, *outdev; -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ const char *physindev, *physoutdev; -+#endif - void *table_base; - struct ipt_entry *e, *back; - -@@ -281,6 +307,13 @@ - datalen = (*pskb)->len - ip->ihl * 4; - indev = in ? in->name : nulldevname; - outdev = out ? out->name : nulldevname; -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ physindev = ((*pskb)->nf_bridge && (*pskb)->nf_bridge->physindev) ? -+ (*pskb)->nf_bridge->physindev->name : nulldevname; -+ physoutdev = ((*pskb)->nf_bridge && (*pskb)->nf_bridge->physoutdev) ? -+ (*pskb)->nf_bridge->physoutdev->name : nulldevname; -+#endif -+ - /* We handle fragments by dealing with the first fragment as - * if it was a normal packet. All other fragments are treated - * normally, except that they will NEVER match rules that ask -@@ -316,7 +349,15 @@ - IP_NF_ASSERT(e); - IP_NF_ASSERT(back); - (*pskb)->nfcache |= e->nfcache; -- if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) { -+ if (ip_packet_match(ip, indev, -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ physindev, -+#endif -+ outdev, -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ physoutdev, -+#endif -+ &e->ip, offset)) { - struct ipt_entry_target *t; - - if (IPT_MATCH_ITERATE(e, do_match, -diff -Nurb src/linux/linux.stock/net/ipv4/netfilter/ipt_LOG.c src/linux/linux/net/ipv4/netfilter/ipt_LOG.c ---- src/linux/linux.stock/net/ipv4/netfilter/ipt_LOG.c 2004-07-10 23:29:56.000000000 -0400 -+++ src/linux/linux/net/ipv4/netfilter/ipt_LOG.c 2004-07-10 23:46:39.000000000 -0400 -@@ -319,6 +319,18 @@ - prefix == NULL ? loginfo->prefix : prefix, - in ? in->name : "", - out ? out->name : ""); -+#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) -+ if ((*pskb)->nf_bridge) { -+ struct net_device *physindev = (*pskb)->nf_bridge->physindev; -+ struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev; -+ -+ if (physindev && in != physindev) -+ printk("PHYSIN=%s ", physindev->name); -+ if (physoutdev && out != physoutdev) -+ printk("PHYSOUT=%s ", physoutdev->name); -+ } -+#endif -+ - if (in && !out) { - /* MAC logging for input chain only. */ - printk("MAC="); -diff -Nurb src/linux/linux.stock/net/ipv4/netfilter/ipt_physdev.c src/linux/linux/net/ipv4/netfilter/ipt_physdev.c ---- src/linux/linux.stock/net/ipv4/netfilter/ipt_physdev.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/ipv4/netfilter/ipt_physdev.c 2004-07-10 23:46:39.000000000 -0400 -@@ -0,0 +1,127 @@ -+/* Kernel module to match the bridge port in and -+ * out device for IP packets coming into contact with a bridge. */ -+#include -+#include -+#include -+#include -+#include -+#include -+#define MATCH 1 -+#define NOMATCH 0 -+ -+static int -+match(const struct sk_buff *skb, -+ const struct net_device *in, -+ const struct net_device *out, -+ const void *matchinfo, -+ int offset, -+ const void *hdr, -+ u_int16_t datalen, -+ int *hotdrop) -+{ -+ int i; -+ static const char nulldevname[IFNAMSIZ] = { 0 }; -+ const struct ipt_physdev_info *info = matchinfo; -+ unsigned long ret; -+ const char *indev, *outdev; -+ struct nf_bridge_info *nf_bridge; -+ -+ /* Not a bridged IP packet or no info available yet: -+ * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if -+ * the destination device will be a bridge. */ -+ if (!(nf_bridge = skb->nf_bridge)) { -+ /* Return MATCH if the invert flags of the used options are on */ -+ if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && -+ !(info->invert & IPT_PHYSDEV_OP_BRIDGED)) -+ return NOMATCH; -+ if ((info->bitmask & IPT_PHYSDEV_OP_ISIN) && -+ !(info->invert & IPT_PHYSDEV_OP_ISIN)) -+ return NOMATCH; -+ if ((info->bitmask & IPT_PHYSDEV_OP_ISOUT) && -+ !(info->invert & IPT_PHYSDEV_OP_ISOUT)) -+ return NOMATCH; -+ if ((info->bitmask & IPT_PHYSDEV_OP_IN) && -+ !(info->invert & IPT_PHYSDEV_OP_IN)) -+ return NOMATCH; -+ if ((info->bitmask & IPT_PHYSDEV_OP_OUT) && -+ !(info->invert & IPT_PHYSDEV_OP_OUT)) -+ return NOMATCH; -+ return MATCH; -+ } -+ -+ /* This only makes sense in the FORWARD and POSTROUTING chains */ -+ if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && -+ (!!(nf_bridge->mask & BRNF_BRIDGED) ^ -+ !(info->invert & IPT_PHYSDEV_OP_BRIDGED))) -+ return NOMATCH; -+ -+ if ((info->bitmask & IPT_PHYSDEV_OP_ISIN && -+ (!nf_bridge->physindev ^ !!(info->invert & IPT_PHYSDEV_OP_ISIN))) || -+ (info->bitmask & IPT_PHYSDEV_OP_ISOUT && -+ (!nf_bridge->physoutdev ^ !!(info->invert & IPT_PHYSDEV_OP_ISOUT)))) -+ return NOMATCH; -+ -+ if (!(info->bitmask & IPT_PHYSDEV_OP_IN)) -+ goto match_outdev; -+ indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; -+ for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { -+ ret |= (((const unsigned long *)indev)[i] -+ ^ ((const unsigned long *)info->physindev)[i]) -+ & ((const unsigned long *)info->in_mask)[i]; -+ } -+ -+ if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN)) -+ return NOMATCH; -+ -+match_outdev: -+ if (!(info->bitmask & IPT_PHYSDEV_OP_OUT)) -+ return MATCH; -+ outdev = nf_bridge->physoutdev ? -+ nf_bridge->physoutdev->name : nulldevname; -+ for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { -+ ret |= (((const unsigned long *)outdev)[i] -+ ^ ((const unsigned long *)info->physoutdev)[i]) -+ & ((const unsigned long *)info->out_mask)[i]; -+ } -+ -+ return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT); -+} -+ -+static int -+checkentry(const char *tablename, -+ const struct ipt_ip *ip, -+ void *matchinfo, -+ unsigned int matchsize, -+ unsigned int hook_mask) -+{ -+ const struct ipt_physdev_info *info = matchinfo; -+ -+ if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info))) -+ return 0; -+ if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) || -+ info->bitmask & ~IPT_PHYSDEV_OP_MASK) -+ return 0; -+ return 1; -+} -+ -+static struct ipt_match physdev_match = { -+ .name = "physdev", -+ .match = &match, -+ .checkentry = &checkentry, -+ .me = THIS_MODULE, -+}; -+ -+static int __init init(void) -+{ -+ return ipt_register_match(&physdev_match); -+} -+ -+static void __exit fini(void) -+{ -+ ipt_unregister_match(&physdev_match); -+} -+ -+module_init(init); -+module_exit(fini); -+MODULE_LICENSE("GPL"); -+EXPORT_NO_SYMBOLS; diff --git a/obsolete-buildroot/sources/kernel-patches/001-patch-2.4.26-pre5.bz2 b/obsolete-buildroot/sources/kernel-patches/001-patch-2.4.26-pre5.bz2 deleted file mode 100644 index aa934c5a7c..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/001-patch-2.4.26-pre5.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/006-ieee1394-hotplug.bz2 b/obsolete-buildroot/sources/kernel-patches/006-ieee1394-hotplug.bz2 deleted file mode 100644 index b8361ba35b..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/006-ieee1394-hotplug.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/007-scsi_add_remove_single.bz2 b/obsolete-buildroot/sources/kernel-patches/007-scsi_add_remove_single.bz2 deleted file mode 100644 index 0d2ee20a93..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/007-scsi_add_remove_single.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/008-ieee1394-fix.bz2 b/obsolete-buildroot/sources/kernel-patches/008-ieee1394-fix.bz2 deleted file mode 100644 index d88f251349..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/008-ieee1394-fix.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/009-always-inline.bz2 b/obsolete-buildroot/sources/kernel-patches/009-always-inline.bz2 deleted file mode 100644 index 0838fedd6d..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/009-always-inline.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/010-optimize-for-size.bz2 b/obsolete-buildroot/sources/kernel-patches/010-optimize-for-size.bz2 deleted file mode 100644 index 68c19d4bbb..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/010-optimize-for-size.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/012-x86-check_gcc.bz2 b/obsolete-buildroot/sources/kernel-patches/012-x86-check_gcc.bz2 deleted file mode 100644 index f645dc1aa9..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/012-x86-check_gcc.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/017-printk.bz2 b/obsolete-buildroot/sources/kernel-patches/017-printk.bz2 deleted file mode 100644 index da99976164..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/017-printk.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/018-slab-loop-init.bz2 b/obsolete-buildroot/sources/kernel-patches/018-slab-loop-init.bz2 deleted file mode 100644 index dfba2bae58..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/018-slab-loop-init.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/041-changeloop.patch.bz2 b/obsolete-buildroot/sources/kernel-patches/041-changeloop.patch.bz2 deleted file mode 100644 index 9e64eca6b5..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/041-changeloop.patch.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/042-loopfixes.patch.bz2 b/obsolete-buildroot/sources/kernel-patches/042-loopfixes.patch.bz2 deleted file mode 100644 index 456ee6145a..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/042-loopfixes.patch.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/044-streaming_io.bz2 b/obsolete-buildroot/sources/kernel-patches/044-streaming_io.bz2 deleted file mode 100644 index 4f453e1820..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/044-streaming_io.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/062-silence-blk-queue.bz2 b/obsolete-buildroot/sources/kernel-patches/062-silence-blk-queue.bz2 deleted file mode 100644 index 84a9a05c79..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/062-silence-blk-queue.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/063-silence.kbd.patch.bz2 b/obsolete-buildroot/sources/kernel-patches/063-silence.kbd.patch.bz2 deleted file mode 100644 index 04c56d62bc..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/063-silence.kbd.patch.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/064-shutup-md.bz2 b/obsolete-buildroot/sources/kernel-patches/064-shutup-md.bz2 deleted file mode 100644 index 944b12acef..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/064-shutup-md.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/079-jiffies64.bz2 b/obsolete-buildroot/sources/kernel-patches/079-jiffies64.bz2 deleted file mode 100644 index 1b6873d3ec..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/079-jiffies64.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/089-no-touch-makedep.bz2 b/obsolete-buildroot/sources/kernel-patches/089-no-touch-makedep.bz2 deleted file mode 100644 index 2e413ccafc..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/089-no-touch-makedep.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/kernel-patches/100_VERSION.bz2 b/obsolete-buildroot/sources/kernel-patches/100_VERSION.bz2 deleted file mode 100644 index 54d2e6571e..0000000000 Binary files a/obsolete-buildroot/sources/kernel-patches/100_VERSION.bz2 and /dev/null differ diff --git a/obsolete-buildroot/sources/linux.config b/obsolete-buildroot/sources/linux.config deleted file mode 100644 index e33656a9ff..0000000000 --- a/obsolete-buildroot/sources/linux.config +++ /dev/null @@ -1,877 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_X86=y -# CONFIG_SBUS is not set -CONFIG_UID16=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -CONFIG_KMOD=y - -# -# Processor type and features -# -# CONFIG_M386 is not set -# CONFIG_M486 is not set -# CONFIG_M586 is not set -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -# CONFIG_M686 is not set -# CONFIG_MPENTIUMIII is not set -# CONFIG_MPENTIUM4 is not set -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MK8 is not set -CONFIG_MELAN=y -# CONFIG_MCRUSOE is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP2 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MCYRIXIII is not set -# CONFIG_MVIAC3_2 is not set -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -# CONFIG_RWSEM_GENERIC_SPINLOCK is not set -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_X86_L1_CACHE_SHIFT=4 -CONFIG_X86_USE_STRING_486=y -CONFIG_X86_ALIGNMENT_16=y -CONFIG_X86_F00F_WORKS_OK=y -# CONFIG_X86_MCE is not set -# CONFIG_TOSHIBA is not set -# CONFIG_I8K is not set -# CONFIG_MICROCODE is not set -# CONFIG_X86_MSR is not set -# CONFIG_X86_CPUID is not set -# CONFIG_EDD is not set -CONFIG_NOHIGHMEM=y -# CONFIG_HIGHMEM4G is not set -# CONFIG_HIGHMEM64G is not set -# CONFIG_HIGHMEM is not set -CONFIG_MATH_EMULATION=y -CONFIG_MTRR=y -# CONFIG_SMP is not set -# CONFIG_X86_UP_APIC is not set -# CONFIG_X86_UP_IOAPIC is not set -# CONFIG_X86_TSC_DISABLE is not set - -# -# General setup -# -CONFIG_NET=y -CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_ISA=y -CONFIG_PCI_NAMES=y -CONFIG_EISA=y -CONFIG_MCA=y -CONFIG_HOTPLUG=y - -# -# PCMCIA/CardBus support -# -CONFIG_PCMCIA=m -CONFIG_CARDBUS=y -CONFIG_TCIC=y -CONFIG_I82092=y -CONFIG_I82365=y - -# -# PCI Hotplug Support -# -CONFIG_HOTPLUG_PCI=y -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -CONFIG_SYSVIPC=y -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_BINFMT_MISC is not set -# CONFIG_OOM_KILLER is not set -CONFIG_PM=y -CONFIG_APM=y -# CONFIG_APM_IGNORE_USER_SUSPEND is not set -CONFIG_APM_DO_ENABLE=y -# CONFIG_APM_CPU_IDLE is not set -# CONFIG_APM_DISPLAY_BLANK is not set -CONFIG_APM_RTC_IS_GMT=y -CONFIG_APM_ALLOW_INTS=y -CONFIG_APM_REAL_MODE_POWER_OFF=y - -# -# ACPI Support -# -# CONFIG_ACPI is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play configuration -# -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_PS2 is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_CISS_SCSI_TAPE is not set -# CONFIG_CISS_MONITOR_THREAD is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=8192 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_BLK_STATS is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK_DEV=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_FILTER=y -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -# CONFIG_IP_ROUTE_VERBOSE is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -CONFIG_INET_ECN=y -# CONFIG_SYN_COOKIES is not set - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=y -CONFIG_IP_NF_FTP=y -# CONFIG_IP_NF_AMANDA is not set -CONFIG_IP_NF_TFTP=y -CONFIG_IP_NF_IRC=y -CONFIG_IP_NF_QUEUE=y -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_LIMIT=y -CONFIG_IP_NF_MATCH_MAC=y -CONFIG_IP_NF_MATCH_PKTTYPE=y -CONFIG_IP_NF_MATCH_MARK=y -CONFIG_IP_NF_MATCH_MULTIPORT=y -CONFIG_IP_NF_MATCH_TOS=y -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 -CONFIG_IP_NF_MATCH_LENGTH=y -CONFIG_IP_NF_MATCH_TTL=y -CONFIG_IP_NF_MATCH_TCPMSS=y -CONFIG_IP_NF_MATCH_HELPER=y -CONFIG_IP_NF_MATCH_STATE=y -CONFIG_IP_NF_MATCH_CONNTRACK=y -CONFIG_IP_NF_MATCH_UNCLEAN=y -CONFIG_IP_NF_MATCH_OWNER=y -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_MIRROR=y -CONFIG_IP_NF_NAT=y -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_IP_NF_NAT_LOCAL=y -CONFIG_IP_NF_NAT_SNMP_BASIC=y -CONFIG_IP_NF_NAT_IRC=y -CONFIG_IP_NF_NAT_FTP=y -CONFIG_IP_NF_NAT_TFTP=y -CONFIG_IP_NF_MANGLE=y -CONFIG_IP_NF_TARGET_TOS=y -CONFIG_IP_NF_TARGET_ECN=y -CONFIG_IP_NF_TARGET_DSCP=y -CONFIG_IP_NF_TARGET_MARK=y -CONFIG_IP_NF_TARGET_LOG=y -CONFIG_IP_NF_TARGET_ULOG=y -CONFIG_IP_NF_TARGET_TCPMSS=y -CONFIG_IP_NF_ARPTABLES=y -CONFIG_IP_NF_ARPFILTER=y -CONFIG_IP_NF_ARP_MANGLE=y - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -CONFIG_IPV6_SCTP__=y -# CONFIG_IP_SCTP is not set -# CONFIG_SCTP_HMAC_NONE is not set -CONFIG_SCTP_HMAC_SHA1=y -# CONFIG_SCTP_HMAC_MD5 is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -CONFIG_BRIDGE=y -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=y -CONFIG_NET_SCH_HTB=y -CONFIG_NET_SCH_CSZ=y -CONFIG_NET_SCH_HFSC=y -CONFIG_NET_SCH_PRIO=y -CONFIG_NET_SCH_RED=y -CONFIG_NET_SCH_SFQ=y -CONFIG_NET_SCH_TEQL=y -CONFIG_NET_SCH_TBF=y -CONFIG_NET_SCH_GRED=y -CONFIG_NET_SCH_DSMARK=y -CONFIG_NET_SCH_INGRESS=y -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_TCINDEX=y -CONFIG_NET_CLS_ROUTE4=y -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=y -CONFIG_NET_CLS_U32=y -CONFIG_NET_CLS_RSVP=y -CONFIG_NET_CLS_RSVP6=y -CONFIG_NET_CLS_POLICE=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -CONFIG_IDEDISK_STROKE=y -CONFIG_BLK_DEV_IDECS=m -# CONFIG_BLK_DEV_IDECD is not set -# CONFIG_BLK_DEV_IDETAPE is not set -# CONFIG_BLK_DEV_IDEFLOPPY is not set -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_ISAPNP is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y -CONFIG_IDEDMA_PCI_WIP=y -# CONFIG_BLK_DEV_ADMA100 is not set -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_WDC_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_AMD74XX_OVERRIDE is not set -# CONFIG_BLK_DEV_CMD64X is not set -# CONFIG_BLK_DEV_TRIFLEX is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_HPT34X_AUTODMA is not set -# CONFIG_BLK_DEV_HPT366 is not set -# CONFIG_BLK_DEV_PIIX is not set -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX_OLD is not set -# CONFIG_PDC202XX_BURST is not set -# CONFIG_BLK_DEV_PDC202XX_NEW is not set -# CONFIG_BLK_DEV_RZ1000 is not set -# CONFIG_BLK_DEV_SC1200 is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIIMAGE is not set -# CONFIG_BLK_DEV_SIS5513 is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDE_CHIPSETS is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -# CONFIG_BLK_DEV_ATARAID is not set -# CONFIG_BLK_DEV_ATARAID_PDC is not set -# CONFIG_BLK_DEV_ATARAID_HPT is not set -# CONFIG_BLK_DEV_ATARAID_MEDLEY is not set -# CONFIG_BLK_DEV_ATARAID_SII is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# Fusion MPT device support -# -# CONFIG_FUSION is not set -# CONFIG_FUSION_BOOT is not set -# CONFIG_FUSION_ISENSE is not set -# CONFIG_FUSION_CTL is not set -# CONFIG_FUSION_LAN is not set - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=m -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=y -# CONFIG_ETHERTAP is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -# CONFIG_SKMC is not set -# CONFIG_NE2_MCA is not set -# CONFIG_IBMLANA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_AMD8111_ETH is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_B44 is not set -# CONFIG_CS89x0 is not set -# CONFIG_TULIP is not set -# CONFIG_DE4X5 is not set -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -# CONFIG_EEPRO100 is not set -# CONFIG_EEPRO100_PIO is not set -# CONFIG_E100 is not set -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -CONFIG_NATSEMI=y -# CONFIG_NE2K_PCI is not set -# CONFIG_FORCEDETH is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_SUNDANCE_MMIO is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_RHINE_MMIO is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_R8169 is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y -# CONFIG_STRIP is not set -# CONFIG_WAVELAN is not set -# CONFIG_ARLAN is not set -# CONFIG_AIRONET4500 is not set -# CONFIG_AIRONET4500_NONCS is not set -# CONFIG_AIRONET4500_PROC is not set -# CONFIG_AIRO is not set -CONFIG_HERMES=m -CONFIG_HOSTAP=m -# CONFIG_PLX_HERMES is not set -# CONFIG_TMD_HERMES is not set -# CONFIG_PCI_HERMES is not set -# CONFIG_HOSTAP_PLX is not set -# CONFIG_HOSTAP_PCI is not set - -# -# Wireless Pcmcia cards support -# -CONFIG_PCMCIA_HERMES=m -CONFIG_HOSTAP_CS=m -# CONFIG_AIRO_CS is not set -# CONFIG_PCMCIA_ATMEL is not set -CONFIG_NET_WIRELESS=y - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# PCMCIA network device support -# -# CONFIG_NET_PCMCIA is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set -# CONFIG_INPUT_UINPUT is not set - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set - -# -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks -# -# CONFIG_QIC02_TAPE is not set -# CONFIG_IPMI_HANDLER is not set -# CONFIG_IPMI_PANIC_EVENT is not set -# CONFIG_IPMI_DEVICE_INTERFACE is not set -# CONFIG_IPMI_KCS is not set -# CONFIG_IPMI_WATCHDOG is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_SCx200 is not set -# CONFIG_SCx200_GPIO is not set -CONFIG_AMD_RNG=y -# CONFIG_INTEL_RNG is not set -CONFIG_HW_RANDOM=y -# CONFIG_AMD_PM768 is not set -# CONFIG_NVRAM is not set -CONFIG_RTC=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set - -# -# Direct Rendering Manager (XFree86 DRI support) -# -# CONFIG_DRM is not set - -# -# PCMCIA character devices -# -# CONFIG_PCMCIA_SERIAL_CS is not set -# CONFIG_SYNCLINK_CS is not set -# CONFIG_MWAVE is not set -# CONFIG_OBMOUSE is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_QFMT_V2 is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -CONFIG_EXT3_FS=y -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -# CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -CONFIG_TMPFS=y -CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_EXT2_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set -# CONFIG_XFS_FS is not set -# CONFIG_XFS_QUOTA is not set -# CONFIG_XFS_RT is not set -# CONFIG_XFS_TRACE is not set -# CONFIG_XFS_DEBUG is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -# CONFIG_NFS_FS is not set -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_ROOT_NFS is not set -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set -# CONFIG_SUNRPC is not set -# CONFIG_LOCKD is not set -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -# CONFIG_NLS_CODEPAGE_437 is not set -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -# CONFIG_NLS_CODEPAGE_850 is not set -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -# CONFIG_NLS_ISO8859_1 is not set -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Console drivers -# -# CONFIG_VGA_CONSOLE is not set -# CONFIG_VIDEO_SELECT is not set -# CONFIG_MDA_CONSOLE is not set - -# -# Frame-buffer support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB is not set - -# -# Support for USB gadgets -# -# CONFIG_USB_GADGET is not set - -# -# Bluetooth support -# -# CONFIG_BLUEZ is not set - -# -# Kernel hacking -# -# CONFIG_DEBUG_KERNEL is not set -CONFIG_LOG_BUF_SHIFT=0 - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -CONFIG_OPTIMIZE_FOR_SIZE=y -CONFIG_CRC32=y -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y -# CONFIG_FW_LOADER is not set diff --git a/obsolete-buildroot/sources/openssh.client.conffiles b/obsolete-buildroot/sources/openssh.client.conffiles deleted file mode 100644 index cb3c639ba6..0000000000 --- a/obsolete-buildroot/sources/openssh.client.conffiles +++ /dev/null @@ -1 +0,0 @@ -/etc/ssh_config diff --git a/obsolete-buildroot/sources/openssh.client.control b/obsolete-buildroot/sources/openssh.client.control deleted file mode 100644 index 358525098c..0000000000 --- a/obsolete-buildroot/sources/openssh.client.control +++ /dev/null @@ -1,12 +0,0 @@ -Package: openssh-client -Priority: optional -Version: 3.8p1-1 -Architecture: mipsel -Maintainer: below0 -Section: net -Depends: zlib libssl -Source: Embedded in the main OpenWrt buildroot -Description: The OpenSSH client. Allows for access to remote systems via the SSH protocol. - Includes: ssh, scp - - diff --git a/obsolete-buildroot/sources/openssh.client.ex.control b/obsolete-buildroot/sources/openssh.client.ex.control deleted file mode 100644 index 5eb808a979..0000000000 --- a/obsolete-buildroot/sources/openssh.client.ex.control +++ /dev/null @@ -1,12 +0,0 @@ -Package: openssh-client-extras -Priority: optional -Version: 3.8p1-1 -Architecture: mipsel -Maintainer: below0 -Section: net -Depends: openssh-client -Source: Embedded in the main OpenWrt buildroot -Description: Various optional OpenSSH client tools. - Includes: ssh-add, ssh-agent, ssh-keyscan, ssk-keysign - - diff --git a/obsolete-buildroot/sources/openssh.client.preinst b/obsolete-buildroot/sources/openssh.client.preinst deleted file mode 100644 index 029c78978a..0000000000 --- a/obsolete-buildroot/sources/openssh.client.preinst +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# Make sure password and group databases exist -if [ ! -f /etc/passwd ]; then - echo -e "root::0:0::/tmp:/bin/sh\nnobody:x:65534:65534:nobody:/tmp:/bin/sh\nsshd:x:100:65534:sshd:/var:/bin/false\n" > /etc/passwd - [ -f /etc/group ] || echo -e "root:x:0:\nnogroup:x:65534:\n" > /etc/group - echo "\n\nNOTICE: SSH requires proper root password to be configured, set it now." - passwd -fi - diff --git a/obsolete-buildroot/sources/openssh.client.ssh_config b/obsolete-buildroot/sources/openssh.client.ssh_config deleted file mode 100644 index 2692e89137..0000000000 --- a/obsolete-buildroot/sources/openssh.client.ssh_config +++ /dev/null @@ -1,37 +0,0 @@ -# $OpenBSD: ssh_config,v 1.19 2003/08/13 08:46:31 markus Exp $ - -# This is the ssh client system-wide configuration file. See -# ssh_config(5) for more information. This file provides defaults for -# users, and the values can be changed in per-user configuration files -# or on the command line. - -# Configuration data is parsed as follows: -# 1. command line options -# 2. user-specific file -# 3. system-wide file -# Any configuration value is only changed the first time it is set. -# Thus, host-specific definitions should be at the beginning of the -# configuration file, and defaults at the end. - -# Site-wide defaults for various options - -# Host * -# ForwardAgent no -# ForwardX11 no -# RhostsRSAAuthentication no -# RSAAuthentication yes -# PasswordAuthentication yes -# HostbasedAuthentication no -# BatchMode no -# CheckHostIP yes -# AddressFamily any -# ConnectTimeout 0 -# StrictHostKeyChecking ask -# IdentityFile ~/.ssh/identity -# IdentityFile ~/.ssh/id_rsa -# IdentityFile ~/.ssh/id_dsa -# Port 22 -# Protocol 2,1 -# Cipher 3des -# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc -# EscapeChar ~ diff --git a/obsolete-buildroot/sources/openssh.patch b/obsolete-buildroot/sources/openssh.patch deleted file mode 100644 index 7d85a0400e..0000000000 --- a/obsolete-buildroot/sources/openssh.patch +++ /dev/null @@ -1,289 +0,0 @@ ---- openssh-3.6.1p1/Makefile.in.orig 2003-03-20 17:34:34.000000000 -0700 -+++ openssh-3.6.1p1/Makefile.in 2003-04-25 17:09:00.000000000 -0600 -@@ -27,7 +27,7 @@ - RAND_HELPER=$(libexecdir)/ssh-rand-helper - PRIVSEP_PATH=@PRIVSEP_PATH@ - SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ --STRIP_OPT=@STRIP_OPT@ -+STRIP_OPT= - - PATHS= -DSSHDIR=\"$(sysconfdir)\" \ - -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \ ---- openssh-3.8p1/configure.ac.orig 2004-02-23 22:47:04.000000000 -0700 -+++ openssh-3.8p1/configure.ac 2004-03-19 01:41:47.000000000 -0700 -@@ -481,6 +481,9 @@ - [ - AC_MSG_RESULT(no) - AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***]) -+ ], -+ [AC_MSG_RESULT(yes) -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) - ] - ) - -@@ -632,6 +635,9 @@ - else - AC_MSG_WARN([zlib version may have security problems]) - fi -+ ], -+ [AC_MSG_RESULT(yes) -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) - ] - ) - -@@ -696,6 +702,9 @@ - [ - AC_MSG_RESULT(no) - AC_DEFINE(BROKEN_ONE_BYTE_DIRENT_D_NAME) -+ ], -+ [AC_MSG_RESULT(yes) -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) - ] - ) - -@@ -727,6 +736,9 @@ - [ - AC_MSG_RESULT(no) - AC_MSG_ERROR([** Incomplete or missing s/key libraries.]) -+ ], -+ [AC_MSG_RESULT(yes) -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) - ]) - fi - ] -@@ -840,7 +852,11 @@ - ], - [AC_MSG_RESULT(yes)], - [AC_DEFINE(BROKEN_SETRESUID) -- AC_MSG_RESULT(not implemented)] -+ AC_MSG_RESULT(not implemented) -+ ], -+ [AC_MSG_RESULT(yes) -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) -+ ] - ) - ]) - -@@ -854,7 +870,11 @@ - ], - [AC_MSG_RESULT(yes)], - [AC_DEFINE(BROKEN_SETRESGID) -- AC_MSG_RESULT(not implemented)] -+ AC_MSG_RESULT(not implemented) -+ ], -+ [AC_MSG_RESULT(yes) -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) -+ ] - ) - ]) - -@@ -890,6 +910,9 @@ - AC_MSG_RESULT(no) - AC_DEFINE(BROKEN_SNPRINTF) - AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor]) -+ ], -+ [AC_MSG_RESULT(yes) -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) - ] - ) - fi -@@ -963,7 +986,10 @@ - [ - AC_MSG_RESULT(no) - AC_DEFINE(SSHD_ACQUIRES_CTTY) -- ] -+ ], -+ [AC_MSG_RESULT(yes) -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) -+ ] - ) - fi - -@@ -1096,6 +1122,10 @@ - [ - AC_MSG_RESULT(not found) - AC_MSG_ERROR(OpenSSL version header not found.) -+ ], -+ [ -+ ssl_header_ver="0x0090704fL (OpenSSL 0.9.7d 17 Mar 2004)" -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to $ssl_header_ver]) - ] - ) - -@@ -1129,6 +1159,10 @@ - [ - AC_MSG_RESULT(not found) - AC_MSG_ERROR(OpenSSL library not found.) -+ ], -+ [ -+ ssl_header_ver="0x0090704fL (OpenSSL 0.9.7d 17 Mar 2004)" -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to $ssl_library_ver]) - ] - ) - -@@ -1148,7 +1182,11 @@ - AC_MSG_ERROR([Your OpenSSL headers do not match your library. - Check config.log for details. - Also see contrib/findssl.sh for help identifying header/library mismatches.]) -- ] -+ ], -+ [ -+ AC_MSG_RESULT(yes) -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) -+ ] - ) - - # Some systems want crypt() from libcrypt, *not* the version in OpenSSL, -@@ -1183,6 +1221,11 @@ - # Default to use of the rand helper if OpenSSL doesn't - # seed itself - USE_RAND_HELPER=yes -+ ], -+ [ -+ OPENSSL_SEEDS_ITSELF=yes -+ AC_MSG_RESULT(yes) -+ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) - ] - ) - -@@ -1773,7 +1816,8 @@ - #else - main() { exit(0); } - #endif -- ], [ true ], [ AC_DEFINE(BROKEN_SNPRINTF) ] -+ ], [ true ], [ AC_DEFINE(BROKEN_SNPRINTF) ], -+ [ true ] - ) - fi - -@@ -1893,6 +1937,7 @@ - } - ], - [ ac_cv_have_accrights_in_msghdr="yes" ], -+ [ ac_cv_have_accrights_in_msghdr="no" ], - [ ac_cv_have_accrights_in_msghdr="no" ] - ) - ]) -@@ -1917,7 +1962,8 @@ - } - ], - [ ac_cv_have_control_in_msghdr="yes" ], -- [ ac_cv_have_control_in_msghdr="no" ] -+ [ ac_cv_have_control_in_msghdr="no" ], -+ [ ac_cv_have_control_in_msghdr="yes" ] - ) - ]) - if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then -@@ -2229,12 +2275,9 @@ - ) - fi - fi --AC_CHECK_FILE("/dev/ptc", -- [ -- AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC) -- have_dev_ptc=1 -- ] --) -+AC_MSG_CHECKING([for "/dev/ptc"]) -+AC_MSG_RESULT(no) -+have_dev_ptc=0 - - # Options from here on. Some of these are preset by platform above - AC_ARG_WITH(mantype, -@@ -2329,15 +2372,8 @@ - fi - - # check for /etc/default/login and use it if present. --AC_ARG_ENABLE(etc-default-login, -- [ --disable-etc-default-login Disable using PATH from /etc/default/login [no]],, --[ --AC_CHECK_FILE("/etc/default/login", [ external_path_file=/etc/default/login ]) -- --if test "x$external_path_file" = "x/etc/default/login"; then -- AC_DEFINE(HAVE_ETC_DEFAULT_LOGIN) --fi --]) -+AC_MSG_CHECKING([for "/etc/default/login"]) -+AC_MSG_RESULT(no) - - dnl BSD systems use /etc/login.conf so --with-default-path= has no effect - if test $ac_cv_func_login_getcapbool = "yes" -a \ ---- openssh-3.8p1.orig/sshd_config Fri Sep 27 05:21:58 2002 -+++ openssh-3.8p1/sshd_config Mon Mar 17 14:55:00 2003 -@@ -89,5 +89,8 @@ - #Banner /some/path - #VerifyReverseMapping no - -+ClientAliveInterval 15 -+ClientAliveCountMax 4 -+ - # override default of no subsystems --Subsystem sftp /usr/libexec/sftp-server -+Subsystem sftp /usr/sbin/sftp-server ---- openssh-3.6.1p1/S50sshd Fri Sep 27 05:21:58 2002 -+++ openssh-3.6.1p1/S50sshd Mon Mar 17 14:55:00 2003 -@@ -0,0 +1,64 @@ -+#!/bin/sh -+# -+# sshd Starts sshd. -+# -+ -+# Make sure the ssh-keygen progam exists -+[ -f /usr/bin/ssh-keygen ] || exit 0 -+ -+# Check for the SSH1 RSA key -+if [ ! -f /etc/ssh_host_key ] ; then -+ echo Generating RSA Key... -+ /usr/bin/ssh-keygen -t rsa1 -f /etc/ssh_host_key -C '' -N '' -+fi -+ -+# Check for the SSH2 RSA key -+if [ ! -f /etc/ssh_host_rsa_key ] ; then -+ echo Generating RSA Key... -+ /usr/bin/ssh-keygen -t rsa -f /etc/ssh_host_rsa_key -C '' -N '' -+fi -+ -+# Check for the SSH2 DSA key -+if [ ! -f /etc/ssh_host_dsa_key ] ; then -+ echo Generating DSA Key... -+ echo THIS CAN TAKE A MINUTE OR TWO DEPENDING ON YOUR PROCESSOR! -+ echo -+ /usr/bin/ssh-keygen -t dsa -f /etc/ssh_host_dsa_key -C '' -N '' -+fi -+ -+umask 077 -+ -+start() { -+ echo -n "Starting sshd: " -+ /usr/sbin/sshd -+ touch /var/lock/sshd -+ echo "OK" -+} -+stop() { -+ echo -n "Stopping sshd: " -+ killall sshd -+ rm -f /var/lock/sshd -+ echo "OK" -+} -+restart() { -+ stop -+ start -+} -+ -+case "$1" in -+ start) -+ start -+ ;; -+ stop) -+ stop -+ ;; -+ restart|reload) -+ restart -+ ;; -+ *) -+ echo $"Usage: $0 {start|stop|restart}" -+ exit 1 -+esac -+ -+exit $? -+ diff --git a/obsolete-buildroot/sources/openssh.server.S50sshd-ipk b/obsolete-buildroot/sources/openssh.server.S50sshd-ipk deleted file mode 100644 index 6f77ad9b1c..0000000000 --- a/obsolete-buildroot/sources/openssh.server.S50sshd-ipk +++ /dev/null @@ -1,45 +0,0 @@ -#!/bin/sh -# -# sshd Starts sshd. -# - -mkdir -p /var/lock -mkdir -p /var/empty -chmod 600 /var/empty - -umask 077 - -start() { - echo -n "Starting sshd: " - /usr/sbin/sshd - touch /var/lock/sshd - echo "OK" -} -stop() { - echo -n "Stopping sshd: " - killall sshd - rm -f /var/lock/sshd - echo "OK" -} -restart() { - stop - start -} - -case "$1" in - start) - start - ;; - stop) - stop - ;; - restart|reload) - restart - ;; - *) - echo $"Usage: $0 {start|stop|restart}" - exit 1 -esac - -exit $? - diff --git a/obsolete-buildroot/sources/openssh.server.conffiles b/obsolete-buildroot/sources/openssh.server.conffiles deleted file mode 100644 index 5877b3bdbc..0000000000 --- a/obsolete-buildroot/sources/openssh.server.conffiles +++ /dev/null @@ -1 +0,0 @@ -/etc/sshd_config diff --git a/obsolete-buildroot/sources/openssh.server.control b/obsolete-buildroot/sources/openssh.server.control deleted file mode 100644 index 943da932d3..0000000000 --- a/obsolete-buildroot/sources/openssh.server.control +++ /dev/null @@ -1,13 +0,0 @@ -Package: openssh-server -Priority: optional -Version: 3.8p1-1 -Architecture: mipsel -Maintainer: below0 -Section: net -Depends: zlib libssl -Source: Embedded in the main OpenWrt buildroot -Description: The OpenSSH server daemon. - Allows for access to the system via the SSH client. - Includes: sshd, ssh-keygen - - diff --git a/obsolete-buildroot/sources/openssh.server.postinst b/obsolete-buildroot/sources/openssh.server.postinst deleted file mode 100644 index 16d2bf4d76..0000000000 --- a/obsolete-buildroot/sources/openssh.server.postinst +++ /dev/null @@ -1,20 +0,0 @@ -#!/bin/sh - -# Check for the SSH1 RSA key -if [ ! -f /etc/ssh_host_key ] ; then - echo Generating RSA Key... - /usr/bin/ssh-keygen -t rsa1 -f /etc/ssh_host_key -C '' -N '' -fi - -# Check for the SSH2 RSA key -if [ ! -f /etc/ssh_host_rsa_key ] ; then - echo Generating RSA Key... - /usr/bin/ssh-keygen -t rsa -f /etc/ssh_host_rsa_key -C '' -N '' -fi - -# Check for the SSH2 DSA key -if [ ! -f /etc/ssh_host_dsa_key ] ; then - echo "Generating DSA Key... (Takes a few minutes)" - /usr/bin/ssh-keygen -t dsa -f /etc/ssh_host_dsa_key -C '' -N '' -fi - diff --git a/obsolete-buildroot/sources/openssh.server.preinst b/obsolete-buildroot/sources/openssh.server.preinst deleted file mode 100644 index 029c78978a..0000000000 --- a/obsolete-buildroot/sources/openssh.server.preinst +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/sh - -# Make sure password and group databases exist -if [ ! -f /etc/passwd ]; then - echo -e "root::0:0::/tmp:/bin/sh\nnobody:x:65534:65534:nobody:/tmp:/bin/sh\nsshd:x:100:65534:sshd:/var:/bin/false\n" > /etc/passwd - [ -f /etc/group ] || echo -e "root:x:0:\nnogroup:x:65534:\n" > /etc/group - echo "\n\nNOTICE: SSH requires proper root password to be configured, set it now." - passwd -fi - diff --git a/obsolete-buildroot/sources/openssh.server.sshd_config b/obsolete-buildroot/sources/openssh.server.sshd_config deleted file mode 100644 index 22e5dc2128..0000000000 --- a/obsolete-buildroot/sources/openssh.server.sshd_config +++ /dev/null @@ -1,100 +0,0 @@ -# $OpenBSD: sshd_config,v 1.68 2003/12/29 16:39:50 millert Exp $ - -# This is the sshd server system-wide configuration file. See -# sshd_config(5) for more information. - -# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin - -# The strategy used for options in the default sshd_config shipped with -# OpenSSH is to specify options with their default value where -# possible, but leave them commented. Uncommented options change a -# default value. - -#Port 22 -#Protocol 2,1 -#ListenAddress 0.0.0.0 -#ListenAddress :: - -# HostKey for protocol version 1 -#HostKey /etc/ssh_host_key -# HostKeys for protocol version 2 -#HostKey /etc/ssh_host_rsa_key -#HostKey /etc/ssh_host_dsa_key - -# Lifetime and size of ephemeral version 1 server key -#KeyRegenerationInterval 1h -#ServerKeyBits 768 - -# Logging -#obsoletes QuietMode and FascistLogging -#SyslogFacility AUTH -#LogLevel INFO - -# Authentication: - -#LoginGraceTime 2m -#PermitRootLogin yes -#StrictModes yes - -#RSAAuthentication yes -#PubkeyAuthentication yes -#AuthorizedKeysFile .ssh/authorized_keys - -# For this to work you will also need host keys in /etc/ssh_known_hosts -#RhostsRSAAuthentication no -# similar for protocol version 2 -#HostbasedAuthentication no -# Change to yes if you don't trust ~/.ssh/known_hosts for -# RhostsRSAAuthentication and HostbasedAuthentication -#IgnoreUserKnownHosts no -# Don't read the user's ~/.rhosts and ~/.shosts files -#IgnoreRhosts yes - -# To disable tunneled clear text passwords, change to no here! -#PasswordAuthentication yes -#PermitEmptyPasswords no - -# Change to no to disable s/key passwords -#ChallengeResponseAuthentication yes - -# Kerberos options -#KerberosAuthentication no -#KerberosOrLocalPasswd yes -#KerberosTicketCleanup yes -#KerberosGetAFSToken no - -# GSSAPI options -#GSSAPIAuthentication no -#GSSAPICleanupCredentials yes - -# Set this to 'yes' to enable PAM authentication (via challenge-response) -# and session processing. Depending on your PAM configuration, this may -# bypass the setting of 'PasswordAuthentication' and 'PermitEmptyPasswords' -#UsePAM no - -#AllowTcpForwarding yes -#GatewayPorts no -#X11Forwarding no -#X11DisplayOffset 10 -#X11UseLocalhost yes -#PrintMotd yes -#PrintLastLog yes -#TCPKeepAlive yes -#UseLogin no -#UsePrivilegeSeparation yes -#PermitUserEnvironment no -#Compression yes -#ClientAliveInterval 0 -#ClientAliveCountMax 3 -#UseDNS yes -#PidFile /var/run/sshd.pid -#MaxStartups 10 - -# no default banner path -#Banner /some/path - -ClientAliveInterval 15 -ClientAliveCountMax 4 - -# override default of no subsystems -Subsystem sftp /usr/sbin/sftp-server diff --git a/obsolete-buildroot/sources/openssh.sftp-client.control b/obsolete-buildroot/sources/openssh.sftp-client.control deleted file mode 100644 index 12949f18f3..0000000000 --- a/obsolete-buildroot/sources/openssh.sftp-client.control +++ /dev/null @@ -1,12 +0,0 @@ -Package: openssh-sftp-client -Priority: optional -Version: 3.8p1-1 -Architecture: mipsel -Maintainer: below0 -Section: net -Depends: openssh-client -Source: Embedded in the main OpenWrt buildroot -Description: OpenSSH Secure FTP server. - Includes: sftp-server - - diff --git a/obsolete-buildroot/sources/openssh.sftp-server.control b/obsolete-buildroot/sources/openssh.sftp-server.control deleted file mode 100644 index 45f5c9aaea..0000000000 --- a/obsolete-buildroot/sources/openssh.sftp-server.control +++ /dev/null @@ -1,12 +0,0 @@ -Package: openssh-sftp-server -Priority: optional -Version: 3.8p1-1 -Architecture: mipsel -Maintainer: below0 -Section: net -Depends: openssh-server -Source: Embedded in the main OpenWrt buildroot -Description: OpenSSH Secure FTP server. - Includes: sftp-server - - diff --git a/obsolete-buildroot/sources/openssl.control b/obsolete-buildroot/sources/openssl.control deleted file mode 100644 index cc679a6569..0000000000 --- a/obsolete-buildroot/sources/openssl.control +++ /dev/null @@ -1,9 +0,0 @@ -Package: openssl -Priority: optional -Version: 0.9.7d-1 -Architecture: mipsel -Maintainer: below0 -Section: libs -Source: Embedded in the main OpenWrt buildroot -Description: OpenSSL libraries used for SSL encryption. - diff --git a/obsolete-buildroot/sources/openssl.patch b/obsolete-buildroot/sources/openssl.patch deleted file mode 100644 index 2e8d50f1cb..0000000000 --- a/obsolete-buildroot/sources/openssl.patch +++ /dev/null @@ -1,238 +0,0 @@ ---- openssl-0.9.7.orig/Configure -+++ openssl-0.9.7/Configure -@@ -1,4 +1,4 @@ --: -+#!/usr/bin/perl - eval 'exec perl -S $0 ${1+"$@"}' - if $running_under_some_shell; - ## -@@ -373,6 +373,40 @@ - # assembler versions -- currently defunct: - ##"OpenBSD-alpha","gcc:-DTERMIOS -O3 -fomit-frame-pointer:::(unknown):SIXTY_FOUR_BIT_LONG DES_INT DES_PTR DES_RISC2:${alpha_asm}", - -+# Sane Linux configuration values, stolen from the Debian package.... -+"linux-alpha","gcc:-DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-alpha-ev4","gcc:-DTERMIO -O3 -mcpu=ev4 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-alpha-ev5","gcc:-DTERMIO -O3 -mcpu=ev5 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-arm","gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG DES_RISC1::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-freebsd-alpha","gcc:-DTERMIOS -O -fomit-frame-pointer::(unknown):::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_PTR DES_RISC2::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-freebsd-i386", "gcc:-DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O3 -m486 -Wall::-pthread -D_REENTRANT -D_THREAD_SAFE -D_THREADSAFE:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-hppa","gcc:-DB_ENDIAN -DTERMIO -O2 -Wall::-D_REENTRANT::-ldl:BN_LLONG MD2_CHAR RC4_INDEX::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-hurd-i386","gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -m486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-ia64","gcc:-DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK RC4_CHAR:asm/ia64.o:::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+#"linux-i386","gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::dlfcn:linux-shared:-fPIC", -+"linux-i386","gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-i386-i486","gcc:-DL_ENDIAN -DTERMIO -O3 -march=i486 -mcpu=i486 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-i386-i586","gcc:-DL_ENDIAN -DTERMIO -O3 -march=i586 -mcpu=i586 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-i386-i686/cmov","gcc:-DL_ENDIAN -DTERMIO -O3 -march=i686 -mcpu=i686 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-m68k","gcc:-DB_ENDIAN -DTERMIO -O2 -Wall::-D_REENTRANT::-ldl:BN_LLONG MD2_CHAR RC4_INDEX::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-mips", "gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-mipsel", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-netbsd-i386", "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -m486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-netbsd-m68k", "gcc:-DB_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -Wall::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX DES_UNROLL::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-netbsd-sparc", "gcc:-DB_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -mv8 -Wall::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX DES_UNROLL::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-openbsd-alpha","gcc:-DTERMIOS -O3 -fomit-frame-pointer::(unknown):::SIXTY_FOUR_BIT_LONG DES_INT DES_PTR DES_RISC2::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-openbsd-i386", "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -m486::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_out_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-openbsd-mips","gcc:-O2 -DL_ENDIAN::(unknown)::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC2 DES_PTR BF_PTR:::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-powerpc","gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG DES_UNROLL DES_RISC2 DES_PTR MD2_CHAR RC4_INDEX::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-s390","gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-sh3", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-sh4", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-sh3eb", "gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-sh4eb", "gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-sparc","gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-sparc-v8","gcc:-DB_ENDIAN -DTERMIO -O3 -mcpu=v8 -fomit-frame-pointer -Wall -DBN_DIV2W::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8.o:::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-sparc-v9","gcc:-DB_ENDIAN -DTERMIO -O3 -mcpu=v9 -Wa,-Av8plus -fomit-frame-pointer -Wall -DULTRASPARC -DBN_DIV2W::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8plus.o:::asm/md5-sparcv8plus.o::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", -+"linux-cris", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fpic::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", - # The intel boxes :-), It would be worth seeing if bsdi-gcc can use the - # bn86-elf.o file file since it is hand tweaked assembler. - "linux-elf", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ---- openssl-0.9.7.orig/crypto/md5/asm/md5-sparcv9.S -+++ openssl-0.9.7/crypto/md5/asm/md5-sparcv9.S -@@ -72,14 +72,14 @@ - #define Dval R8 - - #if defined(MD5_BLOCK_DATA_ORDER) --# if defined(OPENSSL_SYSNAME_ULTRASPARC) -+/*# if defined(OPENSSL_SYSNAME_ULTRASPARC)*/ - # define LOAD lda - # define X(i) [%i1+i*4]%asi - # define md5_block md5_block_asm_data_order_aligned - # define ASI_PRIMARY_LITTLE 0x88 --# else -+/*# else - # error "MD5_BLOCK_DATA_ORDER is supported only on UltraSPARC!" --# endif -+# endif*/ - #else - # define LOAD ld - # define X(i) [%i1+i*4] ---- openssl-0.9.7.orig/crypto/opensslconf.h -+++ openssl-0.9.7/crypto/opensslconf.h -@@ -4,17 +4,38 @@ - /* OpenSSL was configured with the following options: */ - #ifndef OPENSSL_DOING_MAKEDEPEND - -+#ifndef OPENSSL_NO_IDEA -+# define OPENSSL_NO_IDEA -+#endif -+#ifndef OPENSSL_NO_MDC2 -+# define OPENSSL_NO_MDC2 -+#endif -+#ifndef OPENSSL_NO_RC5 -+# define OPENSSL_NO_RC5 -+#endif - #ifndef OPENSSL_NO_KRB5 - # define OPENSSL_NO_KRB5 - #endif - - #endif /* OPENSSL_DOING_MAKEDEPEND */ -+#ifndef OPENSSL_THREADS -+# define OPENSSL_THREADS -+#endif - - /* The OPENSSL_NO_* macros are also defined as NO_* if the application - asks for it. This is a transient feature that is provided for those - who haven't had the time to do the appropriate changes in their - applications. */ - #ifdef OPENSSL_ALGORITHM_DEFINES -+# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA) -+# define NO_IDEA -+# endif -+# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2) -+# define NO_MDC2 -+# endif -+# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5) -+# define NO_RC5 -+# endif - # if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5) - # define NO_KRB5 - # endif -@@ -27,7 +48,7 @@ - - #if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ - #if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) --#define OPENSSLDIR "/usr/local/ssl" -+#define OPENSSLDIR "/usr/lib/ssl" - #endif - #endif - -@@ -79,7 +100,7 @@ - - #if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) - #define CONFIG_HEADER_BN_H --#undef BN_LLONG -+#define BN_LLONG - - /* Should we define BN_DIV2W here? */ - -@@ -98,7 +119,7 @@ - #define CONFIG_HEADER_RC4_LOCL_H - /* if this is defined data[i] is used instead of *data, this is a %20 - * speedup on x86 */ --#undef RC4_INDEX -+#define RC4_INDEX - #endif - - #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) -@@ -112,14 +133,14 @@ - /* the following is tweaked from a config script, that is why it is a - * protected undef/define */ - #ifndef DES_PTR --#undef DES_PTR -+#define DES_PTR - #endif - - /* This helps C compiler generate the correct code for multiple functional - * units. It reduces register dependancies at the expense of 2 more - * registers */ - #ifndef DES_RISC1 --#undef DES_RISC1 -+#define DES_RISC1 - #endif - - #ifndef DES_RISC2 -@@ -133,7 +154,7 @@ - /* Unroll the inner loop, this sometimes helps, sometimes hinders. - * Very mucy CPU dependant */ - #ifndef DES_UNROLL --#undef DES_UNROLL -+#define DES_UNROLL - #endif - - /* These default values were supplied by ---- openssl-0.9.7.orig/ssl/ssl_algs.c -+++ openssl-0.9.7/ssl/ssl_algs.c -@@ -109,3 +109,8 @@ - return(1); - } - -+#undef SSLeay_add_ssl_algorithms -+int SSLeay_add_ssl_algorithms(void) -+ { -+ return SSL_library_init(); -+ } ---- openssl-0.9.7.orig/tools/c_rehash.in -+++ openssl-0.9.7/tools/c_rehash.in -@@ -1,4 +1,4 @@ --#!/usr/local/bin/perl -+#!/usr/bin/perl - - - # Perl c_rehash script, scan all files in a directory ---- openssl-0.9.7.orig/util/clean-depend.pl -+++ openssl-0.9.7/util/clean-depend.pl -@@ -1,4 +1,4 @@ --#!/usr/local/bin/perl -w -+#!/usr/bin/perl - # Clean the dependency list in a makefile of standard includes... - # Written by Ben Laurie 19 Jan 1999 - ---- openssl-0.9.7.orig/util/extract-names.pl -+++ openssl-0.9.7/util/extract-names.pl -@@ -1,4 +1,4 @@ --#!/usr/bin/perl -+#!/usr/bin/perl - - $/ = ""; # Eat a paragraph at once. - while() { ---- openssl-0.9.7.orig/util/mkdef.pl -+++ openssl-0.9.7/util/mkdef.pl -@@ -1,4 +1,4 @@ --#!/usr/local/bin/perl -w -+#!/usr/bin/perl - # - # generate a .def file - # ---- openssl-0.9.7.orig/util/mkerr.pl -+++ openssl-0.9.7/util/mkerr.pl -@@ -1,4 +1,4 @@ --#!/usr/local/bin/perl -w -+#!/usr/bin/perl - - my $config = "crypto/err/openssl.ec"; - my $debug = 0; ---- openssl-0.9.7.orig/util/mkstack.pl -+++ openssl-0.9.7/util/mkstack.pl -@@ -1,4 +1,4 @@ --#!/usr/local/bin/perl -w -+#!/usr/bin/perl - - # This is a utility that searches out "DECLARE_STACK_OF()" - # declarations in .h and .c files, and updates/creates/replaces ---- openssl-0.9.7.orig/util/pod2man.pl -+++ openssl-0.9.7/util/pod2man.pl -@@ -1,4 +1,4 @@ --: #!/usr/bin/perl-5.005 -+#!/usr/bin/perl - eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' - if $running_under_some_shell; - ---- openssl-0.9.7.orig/util/selftest.pl -+++ openssl-0.9.7/util/selftest.pl -@@ -1,4 +1,4 @@ --#!/usr/local/bin/perl -w -+#!/usr/bin/perl - # - # Run the test suite and generate a report - # diff --git a/obsolete-buildroot/sources/openwrt-diag.c b/obsolete-buildroot/sources/openwrt-diag.c deleted file mode 100644 index 6d93542f84..0000000000 --- a/obsolete-buildroot/sources/openwrt-diag.c +++ /dev/null @@ -1,145 +0,0 @@ -// replacement diag module -// (c) 2004 openwrt -// mbm at alt dot org -// -// initial release 2004/03/28 - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static void *sbh; - -// v2.x - - - - - -#define DIAG_GPIO (1<<1) -#define DMZ_GPIO (1<<7) - -static void set_gpio(uint32 mask, uint32 value) { - sb_gpiocontrol(sbh,mask,0); - sb_gpioouten(sbh,mask,mask); - sb_gpioout(sbh,mask,value); -} - -static void v2_set_diag(u8 state) { - set_gpio(DIAG_GPIO,state); -} -static void v2_set_dmz(u8 state) { - set_gpio(DMZ_GPIO,state); -} - -// v1.x - - - - - -#define LED_DIAG 0x13 -#define LED_DMZ 0x12 - -static void v1_set_diag(u8 state) { - if (!state) { - *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DIAG)=0xFF; - } else { - *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DIAG); - } -} -static void v1_set_dmz(u8 state) { - if (!state) { - *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DMZ)=0xFF; - } else { - *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DMZ); - } -} - -// - - - - - -static void ignore(u8 ignored) {}; - -// - - - - - -#define BIT_DMZ 0x01 -#define BIT_DIAG 0x04 - -void (*set_diag)(u8 state); -void (*set_dmz)(u8 state); - -static unsigned int diag = 0; -static struct timer_list timer; - -static void diag_change() -{ - printk(KERN_INFO "led -> %02x\n",diag); - - set_diag(0xFF); // off - set_dmz(0xFF); // off - - if(diag & BIT_DIAG) - set_diag(0x00); // on - if(diag & BIT_DMZ) - set_dmz(0x00); // on -} - -static int proc_diag(ctl_table *table, int write, struct file *filp, - void *buffer, size_t *lenp) -{ - int r; - r = proc_dointvec(table, write, filp, buffer, lenp); - if (write && !r) { - diag_change(); - } - return r; -} - -// - - - - - -static struct ctl_table_header *diag_sysctl_header; - -static ctl_table sys_diag[] = { - { - ctl_name: 2000, - procname: "diag", - data: &diag, - maxlen: sizeof(diag), - mode: 0644, - proc_handler: proc_diag - }, - { 0 } -}; - -static int __init diag_init() -{ - u32 board_type; - sbh = sb_kattach(); - sb_gpiosetcore(sbh); - - board_type = sb_boardtype(sbh); - printk(KERN_INFO "diag board_type: %08x\n",board_type); - - if (board_type & 0x400) { - set_diag=v1_set_diag; - set_dmz=v1_set_dmz; - if (board_type==0x41d) { - printk(KERN_INFO "buffalo hack.\n"); - set_diag=ignore; - set_dmz=v2_set_dmz; - } - board_type=1; - } else { - board_type=2; - set_diag=v2_set_diag; - set_dmz=v2_set_dmz; - } - printk(KERN_INFO "using v%d hardware\n",board_type); - - diag_sysctl_header = register_sysctl_table(sys_diag, 0); - diag_change(); - - return 0; -} - -static void __exit diag_exit() -{ - unregister_sysctl_table(diag_sysctl_header); - del_timer(&timer); -} - -module_init(diag_init); -module_exit(diag_exit); diff --git a/obsolete-buildroot/sources/openwrt-linux-netfilter.patch b/obsolete-buildroot/sources/openwrt-linux-netfilter.patch deleted file mode 100644 index 4d8b0a1f62..0000000000 --- a/obsolete-buildroot/sources/openwrt-linux-netfilter.patch +++ /dev/null @@ -1,5823 +0,0 @@ -diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack.h ---- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack.h 2003-08-12 07:43:11.000000000 -0400 -+++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack.h 2004-05-09 04:13:03.000000000 -0400 -@@ -45,39 +45,27 @@ - - #include - #include --#include - - /* per conntrack: protocol private data */ - union ip_conntrack_proto { - /* insert conntrack proto private data here */ -- struct ip_ct_gre gre; - struct ip_ct_tcp tcp; - struct ip_ct_icmp icmp; - }; - - union ip_conntrack_expect_proto { - /* insert expect proto private data here */ -- struct ip_ct_gre_expect gre; - }; - - /* Add protocol helper include file here */ --#include --#include --#include -- - #include - #include --#include - - /* per expectation: application helper private data */ - union ip_conntrack_expect_help { - /* insert conntrack helper private data (expect) here */ -- struct ip_ct_pptp_expect exp_pptp_info; -- struct ip_ct_mms_expect exp_mms_info; -- struct ip_ct_h225_expect exp_h225_info; - struct ip_ct_ftp_expect exp_ftp_info; - struct ip_ct_irc_expect exp_irc_info; -- struct ip_autofw_expect exp_autofw_info; - - #ifdef CONFIG_IP_NF_NAT_NEEDED - union { -@@ -89,21 +77,16 @@ - /* per conntrack: application helper private data */ - union ip_conntrack_help { - /* insert conntrack helper private data (master) here */ -- struct ip_ct_pptp_master ct_pptp_info; -- struct ip_ct_mms_master ct_mms_info; -- struct ip_ct_h225_master ct_h225_info; - struct ip_ct_ftp_master ct_ftp_info; - struct ip_ct_irc_master ct_irc_info; - }; - - #ifdef CONFIG_IP_NF_NAT_NEEDED - #include --#include - - /* per conntrack: nat application helper private data */ - union ip_conntrack_nat_help { - /* insert nat helper private data here */ -- struct ip_nat_pptp nat_pptp_info; - }; - #endif - -@@ -275,9 +258,5 @@ - } - - extern unsigned int ip_conntrack_htable_size; -- --/* connection tracking time out variables. */ --extern int sysctl_ip_conntrack_tcp_timeouts[10]; --extern int sysctl_ip_conntrack_udp_timeouts[2]; - #endif /* __KERNEL__ */ - #endif /* _IP_CONNTRACK_H */ -diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_h323.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_h323.h ---- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_h323.h 2003-07-04 04:12:27.000000000 -0400 -+++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_h323.h 1969-12-31 19:00:00.000000000 -0500 -@@ -1,30 +0,0 @@ --#ifndef _IP_CONNTRACK_H323_H --#define _IP_CONNTRACK_H323_H --/* H.323 connection tracking. */ -- --#ifdef __KERNEL__ --/* Protects H.323 related data */ --DECLARE_LOCK_EXTERN(ip_h323_lock); --#endif -- --/* Default H.225 port */ --#define H225_PORT 1720 -- --/* This structure is per expected connection */ --struct ip_ct_h225_expect { -- u_int16_t port; /* Port of the H.225 helper/RTCP/RTP channel */ -- enum ip_conntrack_dir dir; /* Direction of the original connection */ -- unsigned int offset; /* offset of the address in the payload */ --}; -- --/* This structure exists only once per master */ --struct ip_ct_h225_master { -- int is_h225; /* H.225 or H.245 connection */ --#ifdef CONFIG_IP_NF_NAT_NEEDED -- enum ip_conntrack_dir dir; /* Direction of the original connection */ -- u_int32_t seq[IP_CT_DIR_MAX]; /* Exceptional packet mangling for signal addressess... */ -- unsigned int offset[IP_CT_DIR_MAX]; /* ...and the offset of the addresses in the payload */ --#endif --}; -- --#endif /* _IP_CONNTRACK_H323_H */ -diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_mms.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_mms.h ---- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_mms.h 2003-07-04 04:12:27.000000000 -0400 -+++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_mms.h 1969-12-31 19:00:00.000000000 -0500 -@@ -1,31 +0,0 @@ --#ifndef _IP_CONNTRACK_MMS_H --#define _IP_CONNTRACK_MMS_H --/* MMS tracking. */ -- --#ifdef __KERNEL__ --#include -- --DECLARE_LOCK_EXTERN(ip_mms_lock); -- --#define MMS_PORT 1755 --#define MMS_SRV_MSG_ID 196610 -- --#define MMS_SRV_MSG_OFFSET 36 --#define MMS_SRV_UNICODE_STRING_OFFSET 60 --#define MMS_SRV_CHUNKLENLV_OFFSET 16 --#define MMS_SRV_CHUNKLENLM_OFFSET 32 --#define MMS_SRV_MESSAGELENGTH_OFFSET 8 --#endif -- --/* This structure is per expected connection */ --struct ip_ct_mms_expect { -- u_int32_t len; -- u_int32_t padding; -- u_int16_t port; --}; -- --/* This structure exists only once per master */ --struct ip_ct_mms_master { --}; -- --#endif /* _IP_CONNTRACK_MMS_H */ -diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_pptp.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_pptp.h ---- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_pptp.h 2003-07-04 04:12:27.000000000 -0400 -+++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_pptp.h 1969-12-31 19:00:00.000000000 -0500 -@@ -1,313 +0,0 @@ --/* PPTP constants and structs */ --#ifndef _CONNTRACK_PPTP_H --#define _CONNTRACK_PPTP_H -- --/* state of the control session */ --enum pptp_ctrlsess_state { -- PPTP_SESSION_NONE, /* no session present */ -- PPTP_SESSION_ERROR, /* some session error */ -- PPTP_SESSION_STOPREQ, /* stop_sess request seen */ -- PPTP_SESSION_REQUESTED, /* start_sess request seen */ -- PPTP_SESSION_CONFIRMED, /* session established */ --}; -- --/* state of the call inside the control session */ --enum pptp_ctrlcall_state { -- PPTP_CALL_NONE, -- PPTP_CALL_ERROR, -- PPTP_CALL_OUT_REQ, -- PPTP_CALL_OUT_CONF, -- PPTP_CALL_IN_REQ, -- PPTP_CALL_IN_REP, -- PPTP_CALL_IN_CONF, -- PPTP_CALL_CLEAR_REQ, --}; -- -- --/* conntrack private data */ --struct ip_ct_pptp_master { -- enum pptp_ctrlsess_state sstate; /* session state */ -- -- /* everything below is going to be per-expectation in newnat, -- * since there could be more than one call within one session */ -- enum pptp_ctrlcall_state cstate; /* call state */ -- u_int16_t pac_call_id; /* call id of PAC, host byte order */ -- u_int16_t pns_call_id; /* call id of PNS, host byte order */ --}; -- --/* conntrack_expect private member */ --struct ip_ct_pptp_expect { -- enum pptp_ctrlcall_state cstate; /* call state */ -- u_int16_t pac_call_id; /* call id of PAC */ -- u_int16_t pns_call_id; /* call id of PNS */ --}; -- -- --#ifdef __KERNEL__ -- --#include --DECLARE_LOCK_EXTERN(ip_pptp_lock); -- --#define IP_CONNTR_PPTP PPTP_CONTROL_PORT -- --union pptp_ctrl_union { -- void *rawreq; -- struct PptpStartSessionRequest *sreq; -- struct PptpStartSessionReply *srep; -- struct PptpStopSessionReqest *streq; -- struct PptpStopSessionReply *strep; -- struct PptpOutCallRequest *ocreq; -- struct PptpOutCallReply *ocack; -- struct PptpInCallRequest *icreq; -- struct PptpInCallReply *icack; -- struct PptpInCallConnected *iccon; -- struct PptpClearCallRequest *clrreq; -- struct PptpCallDisconnectNotify *disc; -- struct PptpWanErrorNotify *wanerr; -- struct PptpSetLinkInfo *setlink; --}; -- -- -- --#define PPTP_CONTROL_PORT 1723 -- --#define PPTP_PACKET_CONTROL 1 --#define PPTP_PACKET_MGMT 2 -- --#define PPTP_MAGIC_COOKIE 0x1a2b3c4d -- --struct pptp_pkt_hdr { -- __u16 packetLength; -- __u16 packetType; -- __u32 magicCookie; --}; -- --/* PptpControlMessageType values */ --#define PPTP_START_SESSION_REQUEST 1 --#define PPTP_START_SESSION_REPLY 2 --#define PPTP_STOP_SESSION_REQUEST 3 --#define PPTP_STOP_SESSION_REPLY 4 --#define PPTP_ECHO_REQUEST 5 --#define PPTP_ECHO_REPLY 6 --#define PPTP_OUT_CALL_REQUEST 7 --#define PPTP_OUT_CALL_REPLY 8 --#define PPTP_IN_CALL_REQUEST 9 --#define PPTP_IN_CALL_REPLY 10 --#define PPTP_IN_CALL_CONNECT 11 --#define PPTP_CALL_CLEAR_REQUEST 12 --#define PPTP_CALL_DISCONNECT_NOTIFY 13 --#define PPTP_WAN_ERROR_NOTIFY 14 --#define PPTP_SET_LINK_INFO 15 -- --#define PPTP_MSG_MAX 15 -- --/* PptpGeneralError values */ --#define PPTP_ERROR_CODE_NONE 0 --#define PPTP_NOT_CONNECTED 1 --#define PPTP_BAD_FORMAT 2 --#define PPTP_BAD_VALUE 3 --#define PPTP_NO_RESOURCE 4 --#define PPTP_BAD_CALLID 5 --#define PPTP_REMOVE_DEVICE_ERROR 6 -- --struct PptpControlHeader { -- __u16 messageType; -- __u16 reserved; --}; -- --/* FramingCapability Bitmap Values */ --#define PPTP_FRAME_CAP_ASYNC 0x1 --#define PPTP_FRAME_CAP_SYNC 0x2 -- --/* BearerCapability Bitmap Values */ --#define PPTP_BEARER_CAP_ANALOG 0x1 --#define PPTP_BEARER_CAP_DIGITAL 0x2 -- --struct PptpStartSessionRequest { -- __u16 protocolVersion; -- __u8 reserved1; -- __u8 reserved2; -- __u32 framingCapability; -- __u32 bearerCapability; -- __u16 maxChannels; -- __u16 firmwareRevision; -- __u8 hostName[64]; -- __u8 vendorString[64]; --}; -- --/* PptpStartSessionResultCode Values */ --#define PPTP_START_OK 1 --#define PPTP_START_GENERAL_ERROR 2 --#define PPTP_START_ALREADY_CONNECTED 3 --#define PPTP_START_NOT_AUTHORIZED 4 --#define PPTP_START_UNKNOWN_PROTOCOL 5 -- --struct PptpStartSessionReply { -- __u16 protocolVersion; -- __u8 resultCode; -- __u8 generalErrorCode; -- __u32 framingCapability; -- __u32 bearerCapability; -- __u16 maxChannels; -- __u16 firmwareRevision; -- __u8 hostName[64]; -- __u8 vendorString[64]; --}; -- --/* PptpStopReasons */ --#define PPTP_STOP_NONE 1 --#define PPTP_STOP_PROTOCOL 2 --#define PPTP_STOP_LOCAL_SHUTDOWN 3 -- --struct PptpStopSessionRequest { -- __u8 reason; --}; -- --/* PptpStopSessionResultCode */ --#define PPTP_STOP_OK 1 --#define PPTP_STOP_GENERAL_ERROR 2 -- --struct PptpStopSessionReply { -- __u8 resultCode; -- __u8 generalErrorCode; --}; -- --struct PptpEchoRequest { -- __u32 identNumber; --}; -- --/* PptpEchoReplyResultCode */ --#define PPTP_ECHO_OK 1 --#define PPTP_ECHO_GENERAL_ERROR 2 -- --struct PptpEchoReply { -- __u32 identNumber; -- __u8 resultCode; -- __u8 generalErrorCode; -- __u16 reserved; --}; -- --/* PptpFramingType */ --#define PPTP_ASYNC_FRAMING 1 --#define PPTP_SYNC_FRAMING 2 --#define PPTP_DONT_CARE_FRAMING 3 -- --/* PptpCallBearerType */ --#define PPTP_ANALOG_TYPE 1 --#define PPTP_DIGITAL_TYPE 2 --#define PPTP_DONT_CARE_BEARER_TYPE 3 -- --struct PptpOutCallRequest { -- __u16 callID; -- __u16 callSerialNumber; -- __u32 minBPS; -- __u32 maxBPS; -- __u32 bearerType; -- __u32 framingType; -- __u16 packetWindow; -- __u16 packetProcDelay; -- __u16 reserved1; -- __u16 phoneNumberLength; -- __u16 reserved2; -- __u8 phoneNumber[64]; -- __u8 subAddress[64]; --}; -- --/* PptpCallResultCode */ --#define PPTP_OUTCALL_CONNECT 1 --#define PPTP_OUTCALL_GENERAL_ERROR 2 --#define PPTP_OUTCALL_NO_CARRIER 3 --#define PPTP_OUTCALL_BUSY 4 --#define PPTP_OUTCALL_NO_DIAL_TONE 5 --#define PPTP_OUTCALL_TIMEOUT 6 --#define PPTP_OUTCALL_DONT_ACCEPT 7 -- --struct PptpOutCallReply { -- __u16 callID; -- __u16 peersCallID; -- __u8 resultCode; -- __u8 generalErrorCode; -- __u16 causeCode; -- __u32 connectSpeed; -- __u16 packetWindow; -- __u16 packetProcDelay; -- __u32 physChannelID; --}; -- --struct PptpInCallRequest { -- __u16 callID; -- __u16 callSerialNumber; -- __u32 callBearerType; -- __u32 physChannelID; -- __u16 dialedNumberLength; -- __u16 dialingNumberLength; -- __u8 dialedNumber[64]; -- __u8 dialingNumber[64]; -- __u8 subAddress[64]; --}; -- --/* PptpInCallResultCode */ --#define PPTP_INCALL_ACCEPT 1 --#define PPTP_INCALL_GENERAL_ERROR 2 --#define PPTP_INCALL_DONT_ACCEPT 3 -- --struct PptpInCallReply { -- __u16 callID; -- __u16 peersCallID; -- __u8 resultCode; -- __u8 generalErrorCode; -- __u16 packetWindow; -- __u16 packetProcDelay; -- __u16 reserved; --}; -- --struct PptpInCallConnected { -- __u16 peersCallID; -- __u16 reserved; -- __u32 connectSpeed; -- __u16 packetWindow; -- __u16 packetProcDelay; -- __u32 callFramingType; --}; -- --struct PptpClearCallRequest { -- __u16 callID; -- __u16 reserved; --}; -- --struct PptpCallDisconnectNotify { -- __u16 callID; -- __u8 resultCode; -- __u8 generalErrorCode; -- __u16 causeCode; -- __u16 reserved; -- __u8 callStatistics[128]; --}; -- --struct PptpWanErrorNotify { -- __u16 peersCallID; -- __u16 reserved; -- __u32 crcErrors; -- __u32 framingErrors; -- __u32 hardwareOverRuns; -- __u32 bufferOverRuns; -- __u32 timeoutErrors; -- __u32 alignmentErrors; --}; -- --struct PptpSetLinkInfo { -- __u16 peersCallID; -- __u16 reserved; -- __u32 sendAccm; -- __u32 recvAccm; --}; -- -- --struct pptp_priv_data { -- __u16 call_id; -- __u16 mcall_id; -- __u16 pcall_id; --}; -- --#endif /* __KERNEL__ */ --#endif /* _CONNTRACK_PPTP_H */ -diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h ---- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h 2003-07-04 04:12:27.000000000 -0400 -+++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h 1969-12-31 19:00:00.000000000 -0500 -@@ -1,121 +0,0 @@ --#ifndef _CONNTRACK_PROTO_GRE_H --#define _CONNTRACK_PROTO_GRE_H --#include -- --/* GRE PROTOCOL HEADER */ -- --/* GRE Version field */ --#define GRE_VERSION_1701 0x0 --#define GRE_VERSION_PPTP 0x1 -- --/* GRE Protocol field */ --#define GRE_PROTOCOL_PPTP 0x880B -- --/* GRE Flags */ --#define GRE_FLAG_C 0x80 --#define GRE_FLAG_R 0x40 --#define GRE_FLAG_K 0x20 --#define GRE_FLAG_S 0x10 --#define GRE_FLAG_A 0x80 -- --#define GRE_IS_C(f) ((f)&GRE_FLAG_C) --#define GRE_IS_R(f) ((f)&GRE_FLAG_R) --#define GRE_IS_K(f) ((f)&GRE_FLAG_K) --#define GRE_IS_S(f) ((f)&GRE_FLAG_S) --#define GRE_IS_A(f) ((f)&GRE_FLAG_A) -- --/* GRE is a mess: Four different standards */ --struct gre_hdr { --#if defined(__LITTLE_ENDIAN_BITFIELD) -- __u16 rec:3, -- srr:1, -- seq:1, -- key:1, -- routing:1, -- csum:1, -- version:3, -- reserved:4, -- ack:1; --#elif defined(__BIG_ENDIAN_BITFIELD) -- __u16 csum:1, -- routing:1, -- key:1, -- seq:1, -- srr:1, -- rec:3, -- ack:1, -- reserved:4, -- version:3; --#else --#error "Adjust your defines" --#endif -- __u16 protocol; --}; -- --/* modified GRE header for PPTP */ --struct gre_hdr_pptp { -- __u8 flags; /* bitfield */ -- __u8 version; /* should be GRE_VERSION_PPTP */ -- __u16 protocol; /* should be GRE_PROTOCOL_PPTP */ -- __u16 payload_len; /* size of ppp payload, not inc. gre header */ -- __u16 call_id; /* peer's call_id for this session */ -- __u32 seq; /* sequence number. Present if S==1 */ -- __u32 ack; /* seq number of highest packet recieved by */ -- /* sender in this session */ --}; -- -- --/* this is part of ip_conntrack */ --struct ip_ct_gre { -- unsigned int stream_timeout; -- unsigned int timeout; --}; -- --/* this is part of ip_conntrack_expect */ --struct ip_ct_gre_expect { -- struct ip_ct_gre_keymap *keymap_orig, *keymap_reply; --}; -- --#ifdef __KERNEL__ -- --/* structure for original <-> reply keymap */ --struct ip_ct_gre_keymap { -- struct list_head list; -- -- struct ip_conntrack_tuple tuple; -- struct ip_conntrack_expect *master; --}; -- -- --/* add new tuple->key_reply pair to keymap */ --int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp, -- struct ip_conntrack_tuple *t, -- int reply); -- --/* change an existing keymap entry */ --void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km, -- struct ip_conntrack_tuple *t); -- -- -- --/* get pointer to gre key, if present */ --static inline u_int32_t *gre_key(struct gre_hdr *greh) --{ -- if (!greh->key) -- return NULL; -- if (greh->csum || greh->routing) -- return (u_int32_t *) (greh+sizeof(*greh)+4); -- return (u_int32_t *) (greh+sizeof(*greh)); --} -- --/* get pointer ot gre csum, if present */ --static inline u_int16_t *gre_csum(struct gre_hdr *greh) --{ -- if (!greh->csum) -- return NULL; -- return (u_int16_t *) (greh+sizeof(*greh)); --} -- --#endif /* __KERNEL__ */ -- --#endif /* _CONNTRACK_PROTO_GRE_H */ -diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tftp.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tftp.h ---- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tftp.h 2003-07-04 04:12:27.000000000 -0400 -+++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tftp.h 1969-12-31 19:00:00.000000000 -0500 -@@ -1,13 +0,0 @@ --#ifndef _IP_CT_TFTP --#define _IP_CT_TFTP -- --#define TFTP_PORT 69 -- --struct tftphdr { -- u_int16_t opcode; --}; -- --#define TFTP_OPCODE_READ 1 --#define TFTP_OPCODE_WRITE 2 -- --#endif /* _IP_CT_TFTP */ -diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tuple.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tuple.h ---- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2003-07-04 04:12:27.000000000 -0400 -+++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2004-05-09 04:13:03.000000000 -0400 -@@ -14,7 +14,7 @@ - union ip_conntrack_manip_proto - { - /* Add other protocols here. */ -- u_int32_t all; -+ u_int16_t all; - - struct { - u_int16_t port; -@@ -25,9 +25,6 @@ - struct { - u_int16_t id; - } icmp; -- struct { -- u_int32_t key; -- } gre; - }; - - /* The manipulable part of the tuple. */ -@@ -47,7 +44,7 @@ - u_int32_t ip; - union { - /* Add other protocols here. */ -- u_int64_t all; -+ u_int16_t all; - - struct { - u_int16_t port; -@@ -58,11 +55,6 @@ - struct { - u_int8_t type, code; - } icmp; -- struct { -- u_int16_t protocol; -- u_int8_t version; -- u_int32_t key; -- } gre; - } u; - - /* The protocol. */ -@@ -80,16 +72,10 @@ - #ifdef __KERNEL__ - - #define DUMP_TUPLE(tp) \ --DEBUGP("tuple %p: %u %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n", \ -+DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \ - (tp), (tp)->dst.protonum, \ -- NIPQUAD((tp)->src.ip), ntohl((tp)->src.u.all), \ -- NIPQUAD((tp)->dst.ip), ntohl((tp)->dst.u.all)) -- --#define DUMP_TUPLE_RAW(x) \ -- DEBUGP("tuple %p: %u %u.%u.%u.%u:0x%08x -> %u.%u.%u.%u:0x%08x\n",\ -- (x), (x)->dst.protonum, \ -- NIPQUAD((x)->src.ip), ntohl((x)->src.u.all), \ -- NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.all)) -+ NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \ -+ NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all)) - - #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL) - -diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_nat_pptp.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_nat_pptp.h ---- src/linux/linux/include/linux/netfilter_ipv4/ip_nat_pptp.h 2003-07-04 04:12:27.000000000 -0400 -+++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_nat_pptp.h 1969-12-31 19:00:00.000000000 -0500 -@@ -1,11 +0,0 @@ --/* PPTP constants and structs */ --#ifndef _NAT_PPTP_H --#define _NAT_PPTP_H -- --/* conntrack private data */ --struct ip_nat_pptp { -- u_int16_t pns_call_id; /* NAT'ed PNS call id */ -- u_int16_t pac_call_id; /* NAT'ed PAC call id */ --}; -- --#endif /* _NAT_PPTP_H */ -diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_pool.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_pool.h ---- src/linux/linux/include/linux/netfilter_ipv4/ip_pool.h 2003-07-04 04:12:27.000000000 -0400 -+++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_pool.h 1969-12-31 19:00:00.000000000 -0500 -@@ -1,64 +0,0 @@ --#ifndef _IP_POOL_H --#define _IP_POOL_H -- --/***************************************************************************/ --/* This program is free software; you can redistribute it and/or modify */ --/* it under the terms of the GNU General Public License as published by */ --/* the Free Software Foundation; either version 2 of the License, or */ --/* (at your option) any later version. */ --/* */ --/* This program is distributed in the hope that it will be useful, */ --/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ --/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ --/* GNU General Public License for more details. */ --/* */ --/* You should have received a copy of the GNU General Public License */ --/* along with this program; if not, write to the Free Software */ --/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/ --/***************************************************************************/ -- --/* A sockopt of such quality has hardly ever been seen before on the open -- * market! This little beauty, hardly ever used: above 64, so it's -- * traditionally used for firewalling, not touched (even once!) by the -- * 2.0, 2.2 and 2.4 kernels! -- * -- * Comes with its own certificate of authenticity, valid anywhere in the -- * Free world! -- * -- * Rusty, 19.4.2000 -- */ --#define SO_IP_POOL 81 -- --typedef int ip_pool_t; /* pool index */ --#define IP_POOL_NONE ((ip_pool_t)-1) -- --struct ip_pool_request { -- int op; -- ip_pool_t index; -- u_int32_t addr; -- u_int32_t addr2; --}; -- --/* NOTE: I deliberately break the first cut ippool utility. Nobody uses it. */ -- --#define IP_POOL_BAD001 0x00000010 -- --#define IP_POOL_FLUSH 0x00000011 /* req.index, no arguments */ --#define IP_POOL_INIT 0x00000012 /* from addr to addr2 incl. */ --#define IP_POOL_DESTROY 0x00000013 /* req.index, no arguments */ --#define IP_POOL_ADD_ADDR 0x00000014 /* add addr to pool */ --#define IP_POOL_DEL_ADDR 0x00000015 /* del addr from pool */ --#define IP_POOL_HIGH_NR 0x00000016 /* result in req.index */ --#define IP_POOL_LOOKUP 0x00000017 /* result in addr and addr2 */ --#define IP_POOL_USAGE 0x00000018 /* result in addr */ --#define IP_POOL_TEST_ADDR 0x00000019 /* result (0/1) returned */ -- --#ifdef __KERNEL__ -- --/* NOTE: ip_pool_match() and ip_pool_mod() expect ADDR to be host byte order */ --extern int ip_pool_match(ip_pool_t pool, u_int32_t addr); --extern int ip_pool_mod(ip_pool_t pool, u_int32_t addr, int isdel); -- --#endif -- --#endif /*_IP_POOL_H*/ -diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ipt_pool.h src/linux/linux.stock/include/linux/netfilter_ipv4/ipt_pool.h ---- src/linux/linux/include/linux/netfilter_ipv4/ipt_pool.h 2003-07-04 04:12:27.000000000 -0400 -+++ src/linux/linux.stock/include/linux/netfilter_ipv4/ipt_pool.h 1969-12-31 19:00:00.000000000 -0500 -@@ -1,25 +0,0 @@ --#ifndef _IPT_POOL_H --#define _IPT_POOL_H -- --#include -- --#define IPT_POOL_INV_SRC 0x00000001 --#define IPT_POOL_INV_DST 0x00000002 --#define IPT_POOL_DEL_SRC 0x00000004 --#define IPT_POOL_DEL_DST 0x00000008 --#define IPT_POOL_INV_MOD_SRC 0x00000010 --#define IPT_POOL_INV_MOD_DST 0x00000020 --#define IPT_POOL_MOD_SRC_ACCEPT 0x00000040 --#define IPT_POOL_MOD_DST_ACCEPT 0x00000080 --#define IPT_POOL_MOD_SRC_DROP 0x00000100 --#define IPT_POOL_MOD_DST_DROP 0x00000200 -- --/* match info */ --struct ipt_pool_info --{ -- ip_pool_t src; -- ip_pool_t dst; -- unsigned flags; --}; -- --#endif /*_IPT_POOL_H*/ -diff -Nurb src/linux/linux/net/ipv4/netfilter/Config.in src/linux/linux.stock/net/ipv4/netfilter/Config.in ---- src/linux/linux/net/ipv4/netfilter/Config.in 2004-02-19 06:04:35.000000000 -0500 -+++ src/linux/linux.stock/net/ipv4/netfilter/Config.in 2004-05-09 04:13:03.000000000 -0400 -@@ -7,12 +7,7 @@ - tristate 'Connection tracking (required for masq/NAT)' CONFIG_IP_NF_CONNTRACK - if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then - dep_tristate ' FTP protocol support' CONFIG_IP_NF_FTP $CONFIG_IP_NF_CONNTRACK -- dep_tristate ' TFTP protocol support' CONFIG_IP_NF_TFTP $CONFIG_IP_NF_CONNTRACK -- dep_tristate ' H.323 (netmeeting) support' CONFIG_IP_NF_H323 $CONFIG_IP_NF_CONNTRACK - dep_tristate ' IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK -- dep_tristate ' MMS protocol support' CONFIG_IP_NF_MMS $CONFIG_IP_NF_CONNTRACK -- dep_tristate ' GRE protocol support' CONFIG_IP_NF_CT_PROTO_GRE $CONFIG_IP_NF_CONNTRACK -- dep_tristate ' PPTP protocol support' CONFIG_IP_NF_PPTP $CONFIG_IP_NF_CT_PROTO_GRE - fi - - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -@@ -22,19 +17,11 @@ - if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then - # The simple matches. - dep_tristate ' limit match support' CONFIG_IP_NF_MATCH_LIMIT $CONFIG_IP_NF_IPTABLES -- -- dep_tristate ' IP address pool support' CONFIG_IP_NF_POOL $CONFIG_IP_NF_IPTABLES -- if [ "$CONFIG_IP_NF_POOL" = "y" -o "$CONFIG_IP_NF_POOL" = "m" ]; then -- bool ' enable statistics on pool usage' CONFIG_IP_POOL_STATISTICS n -- fi -- - dep_tristate ' MAC address match support' CONFIG_IP_NF_MATCH_MAC $CONFIG_IP_NF_IPTABLES - dep_tristate ' Packet type match support' CONFIG_IP_NF_MATCH_PKTTYPE $CONFIG_IP_NF_IPTABLES - dep_tristate ' netfilter MARK match support' CONFIG_IP_NF_MATCH_MARK $CONFIG_IP_NF_IPTABLES - dep_tristate ' Multiple port match support' CONFIG_IP_NF_MATCH_MULTIPORT $CONFIG_IP_NF_IPTABLES -- dep_tristate ' Multiple port with ranges match support' CONFIG_IP_NF_MATCH_MPORT $CONFIG_IP_NF_IPTABLES - dep_tristate ' TOS match support' CONFIG_IP_NF_MATCH_TOS $CONFIG_IP_NF_IPTABLES -- dep_tristate ' TIME match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_TIME $CONFIG_IP_NF_IPTABLES - dep_tristate ' ECN match support' CONFIG_IP_NF_MATCH_ECN $CONFIG_IP_NF_IPTABLES - - dep_tristate ' DSCP match support' CONFIG_IP_NF_MATCH_DSCP $CONFIG_IP_NF_IPTABLES -@@ -52,7 +39,6 @@ - fi - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate ' Unclean match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_UNCLEAN $CONFIG_IP_NF_IPTABLES -- dep_tristate ' Webstr match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_WEBSTR $CONFIG_IP_NF_IPTABLES - dep_tristate ' Owner match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_OWNER $CONFIG_IP_NF_IPTABLES - fi - # The targets -@@ -70,29 +56,6 @@ - define_bool CONFIG_IP_NF_NAT_NEEDED y - dep_tristate ' MASQUERADE target support' CONFIG_IP_NF_TARGET_MASQUERADE $CONFIG_IP_NF_NAT - dep_tristate ' REDIRECT target support' CONFIG_IP_NF_TARGET_REDIRECT $CONFIG_IP_NF_NAT -- dep_tristate ' Automatic port forwarding (autofw) target support' CONFIG_IP_NF_AUTOFW $CONFIG_IP_NF_NAT -- dep_tristate ' TRIGGER target support (port-trigger)' CONFIG_IP_NF_TARGET_TRIGGER $CONFIG_IP_NF_NAT -- if [ "$CONFIG_IP_NF_H323" = "m" ]; then -- define_tristate CONFIG_IP_NF_NAT_H323 m -- else -- if [ "$CONFIG_IP_NF_H323" = "y" ]; then -- define_tristate CONFIG_IP_NF_NAT_H323 $CONFIG_IP_NF_NAT -- fi -- fi -- if [ "$CONFIG_IP_NF_PPTP" = "m" ]; then -- define_tristate CONFIG_IP_NF_NAT_PPTP m -- else -- if [ "$CONFIG_IP_NF_PPTP" = "y" ]; then -- define_tristate CONFIG_IP_NF_NAT_PPTP $CONFIG_IP_NF_NAT -- fi -- fi -- if [ "$CONFIG_IP_NF_CT_PROTO_GRE" = "m" ]; then -- define_tristate CONFIG_IP_NF_NAT_PROTO_GRE m -- else -- if [ "$CONFIG_IP_NF_CT_PROTO_GRE" = "y" ]; then -- define_tristate CONFIG_IP_NF_NAT_PROTO_GRE $CONFIG_IP_NF_NAT -- fi -- fi - bool ' NAT of local connections (READ HELP)' CONFIG_IP_NF_NAT_LOCAL - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - dep_tristate ' Basic SNMP-ALG support (EXPERIMENTAL)' CONFIG_IP_NF_NAT_SNMP_BASIC $CONFIG_IP_NF_NAT -@@ -104,13 +67,6 @@ - define_tristate CONFIG_IP_NF_NAT_IRC $CONFIG_IP_NF_NAT - fi - fi -- if [ "$CONFIG_IP_NF_MMS" = "m" ]; then -- define_tristate CONFIG_IP_NF_NAT_MMS m -- else -- if [ "$CONFIG_IP_NF_MMS" = "y" ]; then -- define_tristate CONFIG_IP_NF_NAT_MMS $CONFIG_IP_NF_NAT -- fi -- fi - # If they want FTP, set to $CONFIG_IP_NF_NAT (m or y), - # or $CONFIG_IP_NF_FTP (m or y), whichever is weaker. Argh. - if [ "$CONFIG_IP_NF_FTP" = "m" ]; then -@@ -120,13 +76,6 @@ - define_tristate CONFIG_IP_NF_NAT_FTP $CONFIG_IP_NF_NAT - fi - fi -- if [ "$CONFIG_IP_NF_TFTP" = "m" ]; then -- define_tristate CONFIG_IP_NF_NAT_TFTP m -- else -- if [ "$CONFIG_IP_NF_TFTP" = "y" ]; then -- define_tristate CONFIG_IP_NF_NAT_TFTP $CONFIG_IP_NF_NAT -- fi -- fi - fi - fi - -diff -Nurb src/linux/linux/net/ipv4/netfilter/Makefile src/linux/linux.stock/net/ipv4/netfilter/Makefile ---- src/linux/linux/net/ipv4/netfilter/Makefile 2004-02-19 06:04:35.000000000 -0500 -+++ src/linux/linux.stock/net/ipv4/netfilter/Makefile 2004-05-09 04:13:03.000000000 -0400 -@@ -31,48 +31,20 @@ - # connection tracking - obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o - --# H.323 support --obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o --obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o --ifdef CONFIG_IP_NF_NAT_H323 -- export-objs += ip_conntrack_h323.o --endif -- -- --# connection tracking protocol helpers --obj-$(CONFIG_IP_NF_CT_PROTO_GRE) += ip_conntrack_proto_gre.o --ifdef CONFIG_IP_NF_CT_PROTO_GRE -- export-objs += ip_conntrack_proto_gre.o --endif -- --# NAT protocol helpers --obj-$(CONFIG_IP_NF_NAT_PROTO_GRE) += ip_nat_proto_gre.o -- - # connection tracking helpers --obj-$(CONFIG_IP_NF_MMS) += ip_conntrack_mms.o --ifdef CONFIG_IP_NF_NAT_MMS -- export-objs += ip_conntrack_mms.o --endif --obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o --ifdef CONFIG_IP_NF_NAT_PPTP -- export-objs += ip_conntrack_pptp.o --endif --obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o - obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o - ifdef CONFIG_IP_NF_NAT_FTP - export-objs += ip_conntrack_ftp.o - endif -+ - obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o - ifdef CONFIG_IP_NF_NAT_IRC - export-objs += ip_conntrack_irc.o - endif - - # NAT helpers --obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o --obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o - obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o - obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o --obj-$(CONFIG_IP_NF_NAT_MMS) += ip_nat_mms.o - - # generic IP tables - obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o -@@ -86,19 +58,12 @@ - obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o - obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o - obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o --obj-$(CONFIG_IP_NF_POOL) += ipt_pool.o ip_pool.o - obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o - - obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o - obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o -- --obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o -- - obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o - obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o -- --obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o -- - obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o - obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o - obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o -@@ -109,7 +74,6 @@ - obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o - obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o - obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o --obj-$(CONFIG_IP_NF_MATCH_WEBSTR) += ipt_webstr.o - obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o - - # targets -@@ -125,8 +89,6 @@ - obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o - obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o - obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o --obj-$(CONFIG_IP_NF_AUTOFW) += ip_autofw.o --obj-$(CONFIG_IP_NF_TARGET_TRIGGER) += ipt_TRIGGER.o - - # generic ARP tables - obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_core.c ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c 2003-08-12 07:33:45.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_core.c 2004-05-09 04:13:03.000000000 -0400 -@@ -47,7 +47,11 @@ - - #define IP_CONNTRACK_VERSION "2.1" - -+#if 0 -+#define DEBUGP printk -+#else - #define DEBUGP(format, args...) -+#endif - - DECLARE_RWLOCK(ip_conntrack_lock); - DECLARE_RWLOCK(ip_conntrack_expect_tuple_lock); -@@ -62,29 +66,6 @@ - struct list_head *ip_conntrack_hash; - static kmem_cache_t *ip_conntrack_cachep; - --#define SECS * HZ --#define MINS * 60 SECS --#define HOURS * 60 MINS --#define DAYS * 24 HOURS -- --int sysctl_ip_conntrack_tcp_timeouts[10] = { -- 30 MINS, /* TCP_CONNTRACK_NONE, */ -- 5 DAYS, /* TCP_CONNTRACK_ESTABLISHED, */ -- 2 MINS, /* TCP_CONNTRACK_SYN_SENT, */ -- 60 SECS, /* TCP_CONNTRACK_SYN_RECV, */ -- 2 MINS, /* TCP_CONNTRACK_FIN_WAIT, */ -- 2 MINS, /* TCP_CONNTRACK_TIME_WAIT, */ -- 10 SECS, /* TCP_CONNTRACK_CLOSE, */ -- 60 SECS, /* TCP_CONNTRACK_CLOSE_WAIT, */ -- 30 SECS, /* TCP_CONNTRACK_LAST_ACK, */ -- 2 MINS, /* TCP_CONNTRACK_LISTEN, */ --}; -- --int sysctl_ip_conntrack_udp_timeouts[2] = { -- 30 SECS, /* UNREPLIED */ -- 180 SECS /* ASSURED */ --}; -- - extern struct ip_conntrack_protocol ip_conntrack_generic_protocol; - - static inline int proto_cmpfn(const struct ip_conntrack_protocol *curr, -@@ -129,6 +110,9 @@ - static inline u_int32_t - hash_conntrack(const struct ip_conntrack_tuple *tuple) - { -+#if 0 -+ dump_tuple(tuple); -+#endif - /* ntohl because more differences in low bits. */ - /* To ensure that halves of the same connection don't hash - clash, we add the source per-proto again. */ -@@ -160,8 +144,6 @@ - tuple->dst.ip = iph->daddr; - tuple->dst.protonum = iph->protocol; - -- tuple->src.u.all = tuple->dst.u.all = 0; -- - ret = protocol->pkt_to_tuple((u_int32_t *)iph + iph->ihl, - len - 4*iph->ihl, - tuple); -@@ -177,8 +159,6 @@ - inverse->dst.ip = orig->src.ip; - inverse->dst.protonum = orig->dst.protonum; - -- inverse->src.u.all = inverse->dst.u.all = 0; -- - return protocol->invert_tuple(inverse, orig); - } - -@@ -196,8 +176,8 @@ - static void - destroy_expect(struct ip_conntrack_expect *exp) - { -- DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use)); -- IP_NF_ASSERT(atomic_read(&exp->use)); -+ DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(exp->use)); -+ IP_NF_ASSERT(atomic_read(exp->use)); - IP_NF_ASSERT(!timer_pending(&exp->timeout)); - - kfree(exp); -@@ -267,11 +247,11 @@ - static void unexpect_related(struct ip_conntrack_expect *expect) - { - IP_NF_ASSERT(expect->expectant); -+ IP_NF_ASSERT(expect->expectant->helper); - /* if we are supposed to have a timer, but we can't delete - * it: race condition. __unexpect_related will - * be calledd by timeout function */ -- if (expect->expectant->helper -- && expect->expectant->helper->timeout -+ if (expect->expectant->helper->timeout - && !del_timer(&expect->timeout)) - return; - -@@ -580,6 +560,7 @@ - if (!h) { - /* Locally generated ICMPs will match inverted if they - haven't been SNAT'ed yet */ -+ /* FIXME: NAT code has to handle half-done double NAT --RR */ - if (hooknum == NF_IP_LOCAL_OUT) - h = ip_conntrack_find_get(&origtuple, NULL); - -@@ -725,7 +706,6 @@ - - /* If the expectation is dying, then this is a looser. */ - if (expected -- && expected->expectant->helper - && expected->expectant->helper->timeout - && ! del_timer(&expected->timeout)) - expected = NULL; -@@ -744,7 +724,6 @@ - conntrack->master = expected; - expected->sibling = conntrack; - LIST_DELETE(&ip_conntrack_expect_list, expected); -- INIT_LIST_HEAD(&expected->list); - expected->expectant->expecting--; - nf_conntrack_get(&master_ct(conntrack)->infos[0]); - } -@@ -821,9 +800,23 @@ - int set_reply; - int ret; - -+ /* FIXME: Do this right please. --RR */ - (*pskb)->nfcache |= NFC_UNKNOWN; - - /* Doesn't cover locally-generated broadcast, so not worth it. */ -+#if 0 -+ /* Ignore broadcast: no `connection'. */ -+ if ((*pskb)->pkt_type == PACKET_BROADCAST) { -+ printk("Broadcast packet!\n"); -+ return NF_ACCEPT; -+ } else if (((*pskb)->nh.iph->daddr & htonl(0x000000FF)) -+ == htonl(0x000000FF)) { -+ printk("Should bcast: %u.%u.%u.%u->%u.%u.%u.%u (sk=%p, ptype=%u)\n", -+ NIPQUAD((*pskb)->nh.iph->saddr), -+ NIPQUAD((*pskb)->nh.iph->daddr), -+ (*pskb)->sk, (*pskb)->pkt_type); -+ } -+#endif - - /* Previously seen (loopback)? Ignore. Do this before - fragment check. */ -@@ -943,8 +936,8 @@ - * so there is no need to use the tuple lock too */ - - DEBUGP("ip_conntrack_expect_related %p\n", related_to); -- DEBUGP("tuple: "); DUMP_TUPLE_RAW(&expect->tuple); -- DEBUGP("mask: "); DUMP_TUPLE_RAW(&expect->mask); -+ DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple); -+ DEBUGP("mask: "); DUMP_TUPLE(&expect->mask); - - old = LIST_FIND(&ip_conntrack_expect_list, resent_expect, - struct ip_conntrack_expect *, &expect->tuple, -@@ -954,8 +947,7 @@ - pointing into the payload - otherwise we should have to copy - the data filled out by the helper over the old one */ - DEBUGP("expect_related: resent packet\n"); -- if (related_to->helper && -- related_to->helper->timeout) { -+ if (related_to->helper->timeout) { - if (!del_timer(&old->timeout)) { - /* expectation is dying. Fall through */ - old = NULL; -@@ -970,32 +962,26 @@ - WRITE_UNLOCK(&ip_conntrack_lock); - return -EEXIST; - } -- } else if (related_to->helper && -- related_to->helper->max_expected && -+ } else if (related_to->helper->max_expected && - related_to->expecting >= related_to->helper->max_expected) { - struct list_head *cur_item; - /* old == NULL */ -- if (!(related_to->helper->flags & -- IP_CT_HELPER_F_REUSE_EXPECT)) { -- WRITE_UNLOCK(&ip_conntrack_lock); - if (net_ratelimit()) - printk(KERN_WARNING - "ip_conntrack: max number of expected " - "connections %i of %s reached for " -- "%u.%u.%u.%u->%u.%u.%u.%u\n", -+ "%u.%u.%u.%u->%u.%u.%u.%u%s\n", - related_to->helper->max_expected, - related_to->helper->name, - NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), -- NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); -+ NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip), -+ related_to->helper->flags & IP_CT_HELPER_F_REUSE_EXPECT ? -+ ", reusing" : ""); -+ if (!(related_to->helper->flags & -+ IP_CT_HELPER_F_REUSE_EXPECT)) { -+ WRITE_UNLOCK(&ip_conntrack_lock); - return -EPERM; - } -- DEBUGP("ip_conntrack: max number of expected " -- "connections %i of %s reached for " -- "%u.%u.%u.%u->%u.%u.%u.%u, reusing\n", -- related_to->helper->max_expected, -- related_to->helper->name, -- NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), -- NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); - - /* choose the the oldest expectation to evict */ - list_for_each(cur_item, &related_to->sibling_list) { -@@ -1055,8 +1041,7 @@ - /* add to global list of expectations */ - list_prepend(&ip_conntrack_expect_list, &new->list); - /* add and start timer if required */ -- if (related_to->helper && -- related_to->helper->timeout) { -+ if (related_to->helper->timeout) { - init_timer(&new->timeout); - new->timeout.data = (unsigned long)new; - new->timeout.function = expectation_timed_out; -@@ -1079,10 +1064,11 @@ - - MUST_BE_READ_LOCKED(&ip_conntrack_lock); - WRITE_LOCK(&ip_conntrack_expect_tuple_lock); -+ - DEBUGP("change_expect:\n"); -- DEBUGP("exp tuple: "); DUMP_TUPLE_RAW(&expect->tuple); -- DEBUGP("exp mask: "); DUMP_TUPLE_RAW(&expect->mask); -- DEBUGP("newtuple: "); DUMP_TUPLE_RAW(newtuple); -+ DEBUGP("exp tuple: "); DUMP_TUPLE(&expect->tuple); -+ DEBUGP("exp mask: "); DUMP_TUPLE(&expect->mask); -+ DEBUGP("newtuple: "); DUMP_TUPLE(newtuple); - if (expect->ct_tuple.dst.protonum == 0) { - /* Never seen before */ - DEBUGP("change expect: never seen before\n"); -@@ -1360,8 +1346,6 @@ - 0, NULL }; - - #define NET_IP_CONNTRACK_MAX 2089 --#define NET_IP_CONNTRACK_TCP_TIMEOUTS 2090 --#define NET_IP_CONNTRACK_UDP_TIMEOUTS 2091 - #define NET_IP_CONNTRACK_MAX_NAME "ip_conntrack_max" - - #ifdef CONFIG_SYSCTL -@@ -1370,14 +1354,6 @@ - static ctl_table ip_conntrack_table[] = { - { NET_IP_CONNTRACK_MAX, NET_IP_CONNTRACK_MAX_NAME, &ip_conntrack_max, - sizeof(ip_conntrack_max), 0644, NULL, proc_dointvec }, -- { NET_IP_CONNTRACK_TCP_TIMEOUTS, "ip_conntrack_tcp_timeouts", -- &sysctl_ip_conntrack_tcp_timeouts, -- sizeof(sysctl_ip_conntrack_tcp_timeouts), -- 0644, NULL, &proc_dointvec_jiffies, &sysctl_jiffies }, -- { NET_IP_CONNTRACK_UDP_TIMEOUTS, "ip_conntrack_udp_timeouts", -- &sysctl_ip_conntrack_udp_timeouts, -- sizeof(sysctl_ip_conntrack_udp_timeouts), -- 0644, NULL, &proc_dointvec_jiffies, &sysctl_jiffies }, - { 0 } - }; - -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_ftp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_ftp.c ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_ftp.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_ftp.c 2004-05-09 04:13:03.000000000 -0400 -@@ -24,7 +24,11 @@ - static int loose = 0; - MODULE_PARM(loose, "i"); - -+#if 0 -+#define DEBUGP printk -+#else - #define DEBUGP(format, args...) -+#endif - - static int try_rfc959(const char *, size_t, u_int32_t [], char); - static int try_eprt(const char *, size_t, u_int32_t [], char); -@@ -191,6 +195,16 @@ - } - - if (strnicmp(data, pattern, plen) != 0) { -+#if 0 -+ size_t i; -+ -+ DEBUGP("ftp: string mismatch\n"); -+ for (i = 0; i < plen; i++) { -+ DEBUGFTP("ftp:char %u `%c'(%u) vs `%c'(%u)\n", -+ i, data[i], data[i], -+ pattern[i], pattern[i]); -+ } -+#endif - return 0; - } - -@@ -214,6 +228,7 @@ - return 1; - } - -+/* FIXME: This should be in userspace. Later. */ - static int help(const struct iphdr *iph, size_t len, - struct ip_conntrack *ct, - enum ip_conntrack_info ctinfo) -@@ -249,6 +264,7 @@ - } - - /* Checksum invalid? Ignore. */ -+ /* FIXME: Source route IP option packets --RR */ - if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, - csum_partial((char *)tcph, tcplen, 0))) { - DEBUGP("ftp_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_h323.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_h323.c ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_h323.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_h323.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,302 +0,0 @@ --/* -- * H.323 'brute force' extension for H.323 connection tracking. -- * Jozsef Kadlecsik -- * -- * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project. -- * (http://www.coritel.it/projects/sofia/nat/) -- * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind' -- * the unregistered helpers to the conntrack entries. -- */ -- -- --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include -- --MODULE_AUTHOR("Jozsef Kadlecsik "); --MODULE_DESCRIPTION("H.323 'brute force' connection tracking module"); --MODULE_LICENSE("GPL"); -- --DECLARE_LOCK(ip_h323_lock); --struct module *ip_conntrack_h323 = THIS_MODULE; -- --#define DEBUGP(format, args...) -- --static int h245_help(const struct iphdr *iph, size_t len, -- struct ip_conntrack *ct, -- enum ip_conntrack_info ctinfo) --{ -- struct tcphdr *tcph = (void *)iph + iph->ihl * 4; -- unsigned char *data = (unsigned char *) tcph + tcph->doff * 4; -- unsigned char *data_limit; -- u_int32_t tcplen = len - iph->ihl * 4; -- u_int32_t datalen = tcplen - tcph->doff * 4; -- int dir = CTINFO2DIR(ctinfo); -- struct ip_ct_h225_master *info = &ct->help.ct_h225_info; -- struct ip_conntrack_expect expect, *exp = &expect; -- struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info; -- u_int16_t data_port; -- u_int32_t data_ip; -- unsigned int i; -- -- DEBUGP("ct_h245_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n", -- NIPQUAD(iph->saddr), ntohs(tcph->source), -- NIPQUAD(iph->daddr), ntohs(tcph->dest)); -- -- /* Can't track connections formed before we registered */ -- if (!info) -- return NF_ACCEPT; -- -- /* Until there's been traffic both ways, don't look in packets. */ -- if (ctinfo != IP_CT_ESTABLISHED -- && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { -- DEBUGP("ct_h245_help: Conntrackinfo = %u\n", ctinfo); -- return NF_ACCEPT; -- } -- -- /* Not whole TCP header or too short packet? */ -- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) { -- DEBUGP("ct_h245_help: tcplen = %u\n", (unsigned)tcplen); -- return NF_ACCEPT; -- } -- -- /* Checksum invalid? Ignore. */ -- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, -- csum_partial((char *)tcph, tcplen, 0))) { -- DEBUGP("ct_h245_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", -- tcph, tcplen, NIPQUAD(iph->saddr), -- NIPQUAD(iph->daddr)); -- return NF_ACCEPT; -- } -- -- data_limit = (unsigned char *) data + datalen; -- /* bytes: 0123 45 -- ipadrr port */ -- for (i = 0; data < (data_limit - 5); data++, i++) { -- memcpy(&data_ip, data, sizeof(u_int32_t)); -- if (data_ip == iph->saddr) { -- memcpy(&data_port, data + 4, sizeof(u_int16_t)); -- memset(&expect, 0, sizeof(expect)); -- /* update the H.225 info */ -- DEBUGP("ct_h245_help: new RTCP/RTP requested %u.%u.%u.%u:->%u.%u.%u.%u:%u\n", -- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), -- NIPQUAD(iph->saddr), ntohs(data_port)); -- LOCK_BH(&ip_h323_lock); -- info->is_h225 = H225_PORT + 1; -- exp_info->port = data_port; -- exp_info->dir = dir; -- exp_info->offset = i; -- -- exp->seq = ntohl(tcph->seq) + i; -- -- exp->tuple = ((struct ip_conntrack_tuple) -- { { ct->tuplehash[!dir].tuple.src.ip, -- { 0 } }, -- { data_ip, -- { data_port }, -- IPPROTO_UDP }}); -- exp->mask = ((struct ip_conntrack_tuple) -- { { 0xFFFFFFFF, { 0 } }, -- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); -- -- exp->expectfn = NULL; -- -- /* Ignore failure; should only happen with NAT */ -- ip_conntrack_expect_related(ct, exp); -- -- UNLOCK_BH(&ip_h323_lock); -- } -- } -- -- return NF_ACCEPT; -- --} -- --/* H.245 helper is not registered! */ --static struct ip_conntrack_helper h245 = -- { { NULL, NULL }, -- "H.245", /* name */ -- IP_CT_HELPER_F_REUSE_EXPECT, /* flags */ -- NULL, /* module */ -- 8, /* max_ expected */ -- 240, /* timeout */ -- { { 0, { 0 } }, /* tuple */ -- { 0, { 0 }, IPPROTO_TCP } }, -- { { 0, { 0xFFFF } }, /* mask */ -- { 0, { 0 }, 0xFFFF } }, -- h245_help /* helper */ -- }; -- --static int h225_expect(struct ip_conntrack *ct) --{ -- WRITE_LOCK(&ip_conntrack_lock); -- ct->helper = &h245; -- DEBUGP("h225_expect: helper for %p added\n", ct); -- WRITE_UNLOCK(&ip_conntrack_lock); -- -- return NF_ACCEPT; /* unused */ --} -- --static int h225_help(const struct iphdr *iph, size_t len, -- struct ip_conntrack *ct, -- enum ip_conntrack_info ctinfo) --{ -- struct tcphdr *tcph = (void *)iph + iph->ihl * 4; -- unsigned char *data = (unsigned char *) tcph + tcph->doff * 4; -- unsigned char *data_limit; -- u_int32_t tcplen = len - iph->ihl * 4; -- u_int32_t datalen = tcplen - tcph->doff * 4; -- int dir = CTINFO2DIR(ctinfo); -- struct ip_ct_h225_master *info = &ct->help.ct_h225_info; -- struct ip_conntrack_expect expect, *exp = &expect; -- struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info; -- u_int16_t data_port; -- u_int32_t data_ip; -- unsigned int i; -- -- DEBUGP("ct_h225_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n", -- NIPQUAD(iph->saddr), ntohs(tcph->source), -- NIPQUAD(iph->daddr), ntohs(tcph->dest)); -- -- /* Can't track connections formed before we registered */ -- if (!info) -- return NF_ACCEPT; -- -- /* Until there's been traffic both ways, don't look in packets. */ -- if (ctinfo != IP_CT_ESTABLISHED -- && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { -- DEBUGP("ct_h225_help: Conntrackinfo = %u\n", ctinfo); -- return NF_ACCEPT; -- } -- -- /* Not whole TCP header or too short packet? */ -- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) { -- DEBUGP("ct_h225_help: tcplen = %u\n", (unsigned)tcplen); -- return NF_ACCEPT; -- } -- -- /* Checksum invalid? Ignore. */ -- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, -- csum_partial((char *)tcph, tcplen, 0))) { -- DEBUGP("ct_h225_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", -- tcph, tcplen, NIPQUAD(iph->saddr), -- NIPQUAD(iph->daddr)); -- return NF_ACCEPT; -- } -- -- data_limit = (unsigned char *) data + datalen; -- /* bytes: 0123 45 -- ipadrr port */ -- for (i = 0; data < (data_limit - 5); data++, i++) { -- memcpy(&data_ip, data, sizeof(u_int32_t)); -- if (data_ip == iph->saddr) { -- memcpy(&data_port, data + 4, sizeof(u_int16_t)); -- if (data_port == tcph->source) { -- /* Signal address */ -- DEBUGP("ct_h225_help: sourceCallSignalAddress from %u.%u.%u.%u\n", -- NIPQUAD(iph->saddr)); -- /* Update the H.225 info so that NAT can mangle the address/port -- even when we have no expected connection! */ --#ifdef CONFIG_IP_NF_NAT_NEEDED -- LOCK_BH(&ip_h323_lock); -- info->dir = dir; -- info->seq[IP_CT_DIR_ORIGINAL] = ntohl(tcph->seq) + i; -- info->offset[IP_CT_DIR_ORIGINAL] = i; -- UNLOCK_BH(&ip_h323_lock); --#endif -- } else { -- memset(&expect, 0, sizeof(expect)); -- -- /* update the H.225 info */ -- LOCK_BH(&ip_h323_lock); -- info->is_h225 = H225_PORT; -- exp_info->port = data_port; -- exp_info->dir = dir; -- exp_info->offset = i; -- -- exp->seq = ntohl(tcph->seq) + i; -- -- exp->tuple = ((struct ip_conntrack_tuple) -- { { ct->tuplehash[!dir].tuple.src.ip, -- { 0 } }, -- { data_ip, -- { data_port }, -- IPPROTO_TCP }}); -- exp->mask = ((struct ip_conntrack_tuple) -- { { 0xFFFFFFFF, { 0 } }, -- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); -- -- exp->expectfn = h225_expect; -- -- /* Ignore failure */ -- ip_conntrack_expect_related(ct, exp); -- -- DEBUGP("ct_h225_help: new H.245 requested %u.%u.%u.%u->%u.%u.%u.%u:%u\n", -- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), -- NIPQUAD(iph->saddr), ntohs(data_port)); -- -- UNLOCK_BH(&ip_h323_lock); -- } --#ifdef CONFIG_IP_NF_NAT_NEEDED -- } else if (data_ip == iph->daddr) { -- memcpy(&data_port, data + 4, sizeof(u_int16_t)); -- if (data_port == tcph->dest) { -- /* Signal address */ -- DEBUGP("ct_h225_help: destCallSignalAddress %u.%u.%u.%u\n", -- NIPQUAD(iph->daddr)); -- /* Update the H.225 info so that NAT can mangle the address/port -- even when we have no expected connection! */ -- LOCK_BH(&ip_h323_lock); -- info->dir = dir; -- info->seq[IP_CT_DIR_REPLY] = ntohl(tcph->seq) + i; -- info->offset[IP_CT_DIR_REPLY] = i; -- UNLOCK_BH(&ip_h323_lock); -- } --#endif -- } -- } -- -- return NF_ACCEPT; -- --} -- --static struct ip_conntrack_helper h225 = -- { { NULL, NULL }, -- "H.225", /* name */ -- IP_CT_HELPER_F_REUSE_EXPECT, /* flags */ -- THIS_MODULE, /* module */ -- 2, /* max_expected */ -- 240, /* timeout */ -- { { 0, { __constant_htons(H225_PORT) } }, /* tuple */ -- { 0, { 0 }, IPPROTO_TCP } }, -- { { 0, { 0xFFFF } }, /* mask */ -- { 0, { 0 }, 0xFFFF } }, -- h225_help /* helper */ -- }; -- --static int __init init(void) --{ -- return ip_conntrack_helper_register(&h225); --} -- --static void __exit fini(void) --{ -- /* Unregister H.225 helper */ -- ip_conntrack_helper_unregister(&h225); --} -- --#ifdef CONFIG_IP_NF_NAT_NEEDED --EXPORT_SYMBOL(ip_h323_lock); --#endif -- --module_init(init); --module_exit(fini); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_mms.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_mms.c ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_mms.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_mms.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,292 +0,0 @@ --/* MMS extension for IP connection tracking -- * (C) 2002 by Filip Sneppe -- * based on ip_conntrack_ftp.c and ip_conntrack_irc.c -- * -- * ip_conntrack_mms.c v0.3 2002-09-22 -- * -- * This program is free software; you can redistribute it and/or -- * modify it under the terms of the GNU General Public License -- * as published by the Free Software Foundation; either version -- * 2 of the License, or (at your option) any later version. -- * -- * Module load syntax: -- * insmod ip_conntrack_mms.o ports=port1,port2,...port -- * -- * Please give the ports of all MMS servers You wish to connect to. -- * If you don't specify ports, the default will be TCP port 1755. -- * -- * More info on MMS protocol, firewalls and NAT: -- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp -- * http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp -- * -- * The SDP project people are reverse-engineering MMS: -- * http://get.to/sdp -- */ -- --#include --#include --#include --#include --#include --#include --#include -- --#include --#include --#include -- --DECLARE_LOCK(ip_mms_lock); --struct module *ip_conntrack_mms = THIS_MODULE; -- --#define MAX_PORTS 8 --static int ports[MAX_PORTS]; --static int ports_c; --#ifdef MODULE_PARM --MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); --#endif -- --#define DEBUGP(format, args...) -- --#ifdef CONFIG_IP_NF_NAT_NEEDED --EXPORT_SYMBOL(ip_mms_lock); --#endif -- --MODULE_AUTHOR("Filip Sneppe "); --MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) connection tracking module"); --MODULE_LICENSE("GPL"); -- --/* #define isdigit(c) (c >= '0' && c <= '9') */ -- --/* copied from drivers/usb/serial/io_edgeport.c - not perfect but will do the trick */ --static void unicode_to_ascii (char *string, short *unicode, int unicode_size) --{ -- int i; -- for (i = 0; i < unicode_size; ++i) { -- string[i] = (char)(unicode[i]); -- } -- string[unicode_size] = 0x00; --} -- --__inline static int atoi(char *s) --{ -- int i=0; -- while (isdigit(*s)) { -- i = i*10 + *(s++) - '0'; -- } -- return i; --} -- --/* convert ip address string like "192.168.0.10" to unsigned int */ --__inline static u_int32_t asciiiptoi(char *s) --{ -- unsigned int i, j, k; -- -- for(i=k=0; k<3; ++k, ++s, i<<=8) { -- i+=atoi(s); -- for(j=0; (*(++s) != '.') && (j<3); ++j) -- ; -- } -- i+=atoi(s); -- return ntohl(i); --} -- --int parse_mms(const char *data, -- const unsigned int datalen, -- u_int32_t *mms_ip, -- u_int16_t *mms_proto, -- u_int16_t *mms_port, -- char **mms_string_b, -- char **mms_string_e, -- char **mms_padding_e) --{ -- int unicode_size, i; -- char tempstring[28]; /* "\\255.255.255.255\UDP\65535" */ -- char getlengthstring[28]; -- -- for(unicode_size=0; -- (char) *(data+(MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2)) != (char)0; -- unicode_size++) -- if ((unicode_size == 28) || (MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2 >= datalen)) -- return -1; /* out of bounds - incomplete packet */ -- -- unicode_to_ascii(tempstring, (short *)(data+MMS_SRV_UNICODE_STRING_OFFSET), unicode_size); -- DEBUGP("ip_conntrack_mms: offset 60: %s\n", (const char *)(tempstring)); -- -- /* IP address ? */ -- *mms_ip = asciiiptoi(tempstring+2); -- -- i=sprintf(getlengthstring, "%u.%u.%u.%u", HIPQUAD(*mms_ip)); -- -- /* protocol ? */ -- if(strncmp(tempstring+3+i, "TCP", 3)==0) -- *mms_proto = IPPROTO_TCP; -- else if(strncmp(tempstring+3+i, "UDP", 3)==0) -- *mms_proto = IPPROTO_UDP; -- -- /* port ? */ -- *mms_port = atoi(tempstring+7+i); -- -- /* we store a pointer to the beginning of the "\\a.b.c.d\proto\port" -- unicode string, one to the end of the string, and one to the end -- of the packet, since we must keep track of the number of bytes -- between end of the unicode string and the end of packet (padding) */ -- *mms_string_b = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET); -- *mms_string_e = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET + unicode_size * 2); -- *mms_padding_e = (char *)(data + datalen); /* looks funny, doesn't it */ -- return 0; --} -- -- --static int help(const struct iphdr *iph, size_t len, -- struct ip_conntrack *ct, -- enum ip_conntrack_info ctinfo) --{ -- /* tcplen not negative guaranteed by ip_conntrack_tcp.c */ -- struct tcphdr *tcph = (void *)iph + iph->ihl * 4; -- const char *data = (const char *)tcph + tcph->doff * 4; -- unsigned int tcplen = len - iph->ihl * 4; -- unsigned int datalen = tcplen - tcph->doff * 4; -- int dir = CTINFO2DIR(ctinfo); -- struct ip_conntrack_expect expect, *exp = &expect; -- struct ip_ct_mms_expect *exp_mms_info = &exp->help.exp_mms_info; -- -- u_int32_t mms_ip; -- u_int16_t mms_proto; -- char mms_proto_string[8]; -- u_int16_t mms_port; -- char *mms_string_b, *mms_string_e, *mms_padding_e; -- -- /* Until there's been traffic both ways, don't look in packets. */ -- if (ctinfo != IP_CT_ESTABLISHED -- && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) { -- DEBUGP("ip_conntrack_mms: Conntrackinfo = %u\n", ctinfo); -- return NF_ACCEPT; -- } -- -- /* Not whole TCP header? */ -- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff*4) { -- DEBUGP("ip_conntrack_mms: tcplen = %u\n", (unsigned)tcplen); -- return NF_ACCEPT; -- } -- -- /* Checksum invalid? Ignore. */ -- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, -- csum_partial((char *)tcph, tcplen, 0))) { -- DEBUGP("mms_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", -- tcph, tcplen, NIPQUAD(iph->saddr), -- NIPQUAD(iph->daddr)); -- return NF_ACCEPT; -- } -- -- /* Only look at packets with 0x00030002/196610 on bytes 36->39 of TCP payload */ -- if( (MMS_SRV_MSG_OFFSET < datalen) && -- ((*(u32 *)(data+MMS_SRV_MSG_OFFSET)) == MMS_SRV_MSG_ID)) { -- DEBUGP("ip_conntrack_mms: offset 37: %u %u %u %u, datalen:%u\n", -- (u8)*(data+36), (u8)*(data+37), -- (u8)*(data+38), (u8)*(data+39), -- datalen); -- if(parse_mms(data, datalen, &mms_ip, &mms_proto, &mms_port, -- &mms_string_b, &mms_string_e, &mms_padding_e)) -- if(net_ratelimit()) -- printk(KERN_WARNING -- "ip_conntrack_mms: Unable to parse data payload\n"); -- -- memset(&expect, 0, sizeof(expect)); -- -- sprintf(mms_proto_string, "(%u)", mms_proto); -- DEBUGP("ip_conntrack_mms: adding %s expectation %u.%u.%u.%u -> %u.%u.%u.%u:%u\n", -- mms_proto == IPPROTO_TCP ? "TCP" -- : mms_proto == IPPROTO_UDP ? "UDP":mms_proto_string, -- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), -- NIPQUAD(mms_ip), -- mms_port); -- -- /* it's possible that the client will just ask the server to tunnel -- the stream over the same TCP session (from port 1755): there's -- shouldn't be a need to add an expectation in that case, but it -- makes NAT packet mangling so much easier */ -- LOCK_BH(&ip_mms_lock); -- -- DEBUGP("ip_conntrack_mms: tcph->seq = %u\n", tcph->seq); -- -- exp->seq = ntohl(tcph->seq) + (mms_string_b - data); -- exp_mms_info->len = (mms_string_e - mms_string_b); -- exp_mms_info->padding = (mms_padding_e - mms_string_e); -- exp_mms_info->port = mms_port; -- -- DEBUGP("ip_conntrack_mms: wrote info seq=%u (ofs=%u), len=%d, padding=%u\n", -- exp->seq, (mms_string_e - data), exp_mms_info->len, exp_mms_info->padding); -- -- exp->tuple = ((struct ip_conntrack_tuple) -- { { ct->tuplehash[!dir].tuple.src.ip, { 0 } }, -- { mms_ip, -- { (__u16) ntohs(mms_port) }, -- mms_proto } } -- ); -- exp->mask = ((struct ip_conntrack_tuple) -- { { 0xFFFFFFFF, { 0 } }, -- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); -- exp->expectfn = NULL; -- ip_conntrack_expect_related(ct, &expect); -- UNLOCK_BH(&ip_mms_lock); -- } -- -- return NF_ACCEPT; --} -- --static struct ip_conntrack_helper mms[MAX_PORTS]; --static char mms_names[MAX_PORTS][10]; -- --/* Not __exit: called from init() */ --static void fini(void) --{ -- int i; -- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { -- DEBUGP("ip_conntrack_mms: unregistering helper for port %d\n", -- ports[i]); -- ip_conntrack_helper_unregister(&mms[i]); -- } --} -- --static int __init init(void) --{ -- int i, ret; -- char *tmpname; -- -- if (ports[0] == 0) -- ports[0] = MMS_PORT; -- -- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { -- memset(&mms[i], 0, sizeof(struct ip_conntrack_helper)); -- mms[i].tuple.src.u.tcp.port = htons(ports[i]); -- mms[i].tuple.dst.protonum = IPPROTO_TCP; -- mms[i].mask.src.u.tcp.port = 0xFFFF; -- mms[i].mask.dst.protonum = 0xFFFF; -- mms[i].max_expected = 1; -- mms[i].timeout = 0; -- mms[i].flags = IP_CT_HELPER_F_REUSE_EXPECT; -- mms[i].me = THIS_MODULE; -- mms[i].help = help; -- -- tmpname = &mms_names[i][0]; -- if (ports[i] == MMS_PORT) -- sprintf(tmpname, "mms"); -- else -- sprintf(tmpname, "mms-%d", ports[i]); -- mms[i].name = tmpname; -- -- DEBUGP("ip_conntrack_mms: registering helper for port %d\n", -- ports[i]); -- ret = ip_conntrack_helper_register(&mms[i]); -- -- if (ret) { -- fini(); -- return ret; -- } -- ports_c++; -- } -- return 0; --} -- --module_init(init); --module_exit(fini); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_pptp.c ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_pptp.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,531 +0,0 @@ --/* -- * ip_conntrack_pptp.c - Version 1.11 -- * -- * Connection tracking support for PPTP (Point to Point Tunneling Protocol). -- * PPTP is a a protocol for creating virtual private networks. -- * It is a specification defined by Microsoft and some vendors -- * working with Microsoft. PPTP is built on top of a modified -- * version of the Internet Generic Routing Encapsulation Protocol. -- * GRE is defined in RFC 1701 and RFC 1702. Documentation of -- * PPTP can be found in RFC 2637 -- * -- * (C) 2000-2002 by Harald Welte , -- * -- * Development of this code funded by Astaro AG (http://www.astaro.com/) -- * -- * Limitations: -- * - We blindly assume that control connections are always -- * established in PNS->PAC direction. This is a violation -- * of RFFC2673 -- * -- * TODO: - finish support for multiple calls within one session -- * (needs expect reservations in newnat) -- * - testing of incoming PPTP calls -- */ -- --#include --#include --#include --#include --#include --#include -- --#include --#include --#include --#include -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Harald Welte "); --MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP"); -- --DECLARE_LOCK(ip_pptp_lock); -- --#define DEBUGP(format, args...) -- --#define SECS *HZ --#define MINS * 60 SECS --#define HOURS * 60 MINS --#define DAYS * 24 HOURS -- --#define PPTP_GRE_TIMEOUT (10 MINS) --#define PPTP_GRE_STREAM_TIMEOUT (5 DAYS) -- --static int pptp_expectfn(struct ip_conntrack *ct) --{ -- struct ip_conntrack_expect *exp, *other_exp; -- struct ip_conntrack *master; -- -- DEBUGP("increasing timeouts\n"); -- /* increase timeout of GRE data channel conntrack entry */ -- ct->proto.gre.timeout = PPTP_GRE_TIMEOUT; -- ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT; -- -- master = master_ct(ct); -- if (!master) { -- DEBUGP(" no master!!!\n"); -- return 0; -- } -- -- DEBUGP("completing tuples with ct info\n"); -- /* we can do this, since we're unconfirmed */ -- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key == -- htonl(master->help.ct_pptp_info.pac_call_id)) { -- /* assume PNS->PAC */ -- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = -- htonl(master->help.ct_pptp_info.pns_call_id); -- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = -- htonl(master->help.ct_pptp_info.pns_call_id); -- } else { -- /* assume PAC->PNS */ -- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = -- htonl(master->help.ct_pptp_info.pac_call_id); -- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = -- htonl(master->help.ct_pptp_info.pns_call_id); -- } -- -- return 0; --} -- --/* timeout GRE data connections */ --static int pptp_timeout_related(struct ip_conntrack *ct) --{ -- struct list_head *cur_item; -- struct ip_conntrack_expect *exp; -- -- list_for_each(cur_item, &ct->sibling_list) { -- exp = list_entry(cur_item, struct ip_conntrack_expect, -- expected_list); -- -- if (!exp->sibling) -- continue; -- -- DEBUGP("setting timeout of conntrack %p to 0\n", -- exp->sibling); -- exp->sibling->proto.gre.timeout = 0; -- exp->sibling->proto.gre.stream_timeout = 0; -- ip_ct_refresh(exp->sibling, 0); -- } -- -- return 0; --} -- --/* expect GRE connection in PNS->PAC direction */ --static inline int --exp_gre(struct ip_conntrack *master, -- u_int32_t seq, -- u_int16_t callid, -- u_int16_t peer_callid) --{ -- struct ip_conntrack_expect exp; -- struct ip_conntrack_tuple inv_tuple; -- -- memset(&exp, 0, sizeof(exp)); -- /* tuple in original direction, PAC->PNS */ -- exp.tuple.src.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; -- exp.tuple.src.u.gre.key = htonl(ntohs(peer_callid)); -- exp.tuple.dst.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; -- exp.tuple.dst.u.gre.key = htonl(ntohs(callid)); -- exp.tuple.dst.u.gre.protocol = __constant_htons(GRE_PROTOCOL_PPTP); -- exp.tuple.dst.u.gre.version = GRE_VERSION_PPTP; -- exp.tuple.dst.protonum = IPPROTO_GRE; -- -- exp.mask.src.ip = 0xffffffff; -- exp.mask.src.u.all = 0; -- exp.mask.dst.u.all = 0; -- exp.mask.dst.u.gre.key = 0xffffffff; -- exp.mask.dst.u.gre.version = 0xff; -- exp.mask.dst.u.gre.protocol = 0xffff; -- exp.mask.dst.ip = 0xffffffff; -- exp.mask.dst.protonum = 0xffff; -- -- exp.seq = seq; -- exp.expectfn = pptp_expectfn; -- -- exp.help.exp_pptp_info.pac_call_id = ntohs(callid); -- exp.help.exp_pptp_info.pns_call_id = ntohs(peer_callid); -- -- DEBUGP("calling expect_related "); -- DUMP_TUPLE_RAW(&exp.tuple); -- -- /* Add GRE keymap entries */ -- ip_ct_gre_keymap_add(&exp, &exp.tuple, 0); -- invert_tuplepr(&inv_tuple, &exp.tuple); -- ip_ct_gre_keymap_add(&exp, &inv_tuple, 1); -- -- ip_conntrack_expect_related(master, &exp); -- -- return 0; --} -- --static inline int --pptp_inbound_pkt(struct tcphdr *tcph, -- struct pptp_pkt_hdr *pptph, -- size_t datalen, -- struct ip_conntrack *ct, -- enum ip_conntrack_info ctinfo) --{ -- struct PptpControlHeader *ctlh; -- union pptp_ctrl_union pptpReq; -- -- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; -- u_int16_t msg, *cid, *pcid; -- u_int32_t seq; -- -- ctlh = (struct PptpControlHeader *) -- ((char *) pptph + sizeof(struct pptp_pkt_hdr)); -- pptpReq.rawreq = (void *) -- ((char *) ctlh + sizeof(struct PptpControlHeader)); -- -- msg = ntohs(ctlh->messageType); -- DEBUGP("inbound control message %s\n", strMName[msg]); -- -- switch (msg) { -- case PPTP_START_SESSION_REPLY: -- /* server confirms new control session */ -- if (info->sstate < PPTP_SESSION_REQUESTED) { -- DEBUGP("%s without START_SESS_REQUEST\n", -- strMName[msg]); -- break; -- } -- if (pptpReq.srep->resultCode == PPTP_START_OK) -- info->sstate = PPTP_SESSION_CONFIRMED; -- else -- info->sstate = PPTP_SESSION_ERROR; -- break; -- -- case PPTP_STOP_SESSION_REPLY: -- /* server confirms end of control session */ -- if (info->sstate > PPTP_SESSION_STOPREQ) { -- DEBUGP("%s without STOP_SESS_REQUEST\n", -- strMName[msg]); -- break; -- } -- if (pptpReq.strep->resultCode == PPTP_STOP_OK) -- info->sstate = PPTP_SESSION_NONE; -- else -- info->sstate = PPTP_SESSION_ERROR; -- break; -- -- case PPTP_OUT_CALL_REPLY: -- /* server accepted call, we now expect GRE frames */ -- if (info->sstate != PPTP_SESSION_CONFIRMED) { -- DEBUGP("%s but no session\n", strMName[msg]); -- break; -- } -- if (info->cstate != PPTP_CALL_OUT_REQ && -- info->cstate != PPTP_CALL_OUT_CONF) { -- DEBUGP("%s without OUTCALL_REQ\n", strMName[msg]); -- break; -- } -- if (pptpReq.ocack->resultCode != PPTP_OUTCALL_CONNECT) { -- info->cstate = PPTP_CALL_NONE; -- break; -- } -- -- cid = &pptpReq.ocack->callID; -- pcid = &pptpReq.ocack->peersCallID; -- -- info->pac_call_id = ntohs(*cid); -- -- if (htons(info->pns_call_id) != *pcid) { -- DEBUGP("%s for unknown callid %u\n", -- strMName[msg], ntohs(*pcid)); -- break; -- } -- -- DEBUGP("%s, CID=%X, PCID=%X\n", strMName[msg], -- ntohs(*cid), ntohs(*pcid)); -- -- info->cstate = PPTP_CALL_OUT_CONF; -- -- seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph); -- exp_gre(ct, seq, *cid, *pcid); -- break; -- -- case PPTP_IN_CALL_REQUEST: -- /* server tells us about incoming call request */ -- if (info->sstate != PPTP_SESSION_CONFIRMED) { -- DEBUGP("%s but no session\n", strMName[msg]); -- break; -- } -- pcid = &pptpReq.icack->peersCallID; -- DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid)); -- info->cstate = PPTP_CALL_IN_REQ; -- info->pac_call_id= ntohs(*pcid); -- break; -- -- case PPTP_IN_CALL_CONNECT: -- /* server tells us about incoming call established */ -- if (info->sstate != PPTP_SESSION_CONFIRMED) { -- DEBUGP("%s but no session\n", strMName[msg]); -- break; -- } -- if (info->sstate != PPTP_CALL_IN_REP -- && info->sstate != PPTP_CALL_IN_CONF) { -- DEBUGP("%s but never sent IN_CALL_REPLY\n", -- strMName[msg]); -- break; -- } -- -- pcid = &pptpReq.iccon->peersCallID; -- cid = &info->pac_call_id; -- -- if (info->pns_call_id != ntohs(*pcid)) { -- DEBUGP("%s for unknown CallID %u\n", -- strMName[msg], ntohs(*cid)); -- break; -- } -- -- DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid)); -- info->cstate = PPTP_CALL_IN_CONF; -- -- /* we expect a GRE connection from PAC to PNS */ -- seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph); -- exp_gre(ct, seq, *cid, *pcid); -- -- break; -- -- case PPTP_CALL_DISCONNECT_NOTIFY: -- /* server confirms disconnect */ -- cid = &pptpReq.disc->callID; -- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid)); -- info->cstate = PPTP_CALL_NONE; -- -- /* untrack this call id, unexpect GRE packets */ -- pptp_timeout_related(ct); -- /* NEWNAT: look up exp for call id and unexpct_related */ -- break; -- -- case PPTP_WAN_ERROR_NOTIFY: -- break; -- -- case PPTP_ECHO_REQUEST: -- case PPTP_ECHO_REPLY: -- /* I don't have to explain these ;) */ -- break; -- default: -- DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX) -- ? strMName[msg]:strMName[0], msg); -- break; -- } -- -- return NF_ACCEPT; -- --} -- --static inline int --pptp_outbound_pkt(struct tcphdr *tcph, -- struct pptp_pkt_hdr *pptph, -- size_t datalen, -- struct ip_conntrack *ct, -- enum ip_conntrack_info ctinfo) --{ -- struct PptpControlHeader *ctlh; -- union pptp_ctrl_union pptpReq; -- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; -- u_int16_t msg, *cid, *pcid; -- -- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph)); -- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh)); -- -- msg = ntohs(ctlh->messageType); -- DEBUGP("outbound control message %s\n", strMName[msg]); -- -- switch (msg) { -- case PPTP_START_SESSION_REQUEST: -- /* client requests for new control session */ -- if (info->sstate != PPTP_SESSION_NONE) { -- DEBUGP("%s but we already have one", -- strMName[msg]); -- } -- info->sstate = PPTP_SESSION_REQUESTED; -- break; -- case PPTP_STOP_SESSION_REQUEST: -- /* client requests end of control session */ -- info->sstate = PPTP_SESSION_STOPREQ; -- break; -- -- case PPTP_OUT_CALL_REQUEST: -- /* client initiating connection to server */ -- if (info->sstate != PPTP_SESSION_CONFIRMED) { -- DEBUGP("%s but no session\n", -- strMName[msg]); -- break; -- } -- info->cstate = PPTP_CALL_OUT_REQ; -- /* track PNS call id */ -- cid = &pptpReq.ocreq->callID; -- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid)); -- info->pns_call_id = ntohs(*cid); -- break; -- case PPTP_IN_CALL_REPLY: -- /* client answers incoming call */ -- if (info->cstate != PPTP_CALL_IN_REQ -- && info->cstate != PPTP_CALL_IN_REP) { -- DEBUGP("%s without incall_req\n", -- strMName[msg]); -- break; -- } -- if (pptpReq.icack->resultCode != PPTP_INCALL_ACCEPT) { -- info->cstate = PPTP_CALL_NONE; -- break; -- } -- pcid = &pptpReq.icack->peersCallID; -- if (info->pac_call_id != ntohs(*pcid)) { -- DEBUGP("%s for unknown call %u\n", -- strMName[msg], ntohs(*pcid)); -- break; -- } -- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*pcid)); -- /* part two of the three-way handshake */ -- info->cstate = PPTP_CALL_IN_REP; -- info->pns_call_id = ntohs(pptpReq.icack->callID); -- break; -- -- case PPTP_CALL_CLEAR_REQUEST: -- /* client requests hangup of call */ -- if (info->sstate != PPTP_SESSION_CONFIRMED) { -- DEBUGP("CLEAR_CALL but no session\n"); -- break; -- } -- /* FUTURE: iterate over all calls and check if -- * call ID is valid. We don't do this without newnat, -- * because we only know about last call */ -- info->cstate = PPTP_CALL_CLEAR_REQ; -- break; -- case PPTP_SET_LINK_INFO: -- break; -- case PPTP_ECHO_REQUEST: -- case PPTP_ECHO_REPLY: -- /* I don't have to explain these ;) */ -- break; -- default: -- DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)? -- strMName[msg]:strMName[0], msg); -- /* unknown: no need to create GRE masq table entry */ -- break; -- } -- -- return NF_ACCEPT; --} -- -- --/* track caller id inside control connection, call expect_related */ --static int --conntrack_pptp_help(const struct iphdr *iph, size_t len, -- struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) -- --{ -- struct pptp_pkt_hdr *pptph; -- -- struct tcphdr *tcph = (void *) iph + iph->ihl * 4; -- u_int32_t tcplen = len - iph->ihl * 4; -- u_int32_t datalen = tcplen - tcph->doff * 4; -- void *datalimit; -- int dir = CTINFO2DIR(ctinfo); -- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; -- -- int oldsstate, oldcstate; -- int ret; -- -- /* don't do any tracking before tcp handshake complete */ -- if (ctinfo != IP_CT_ESTABLISHED -- && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) { -- DEBUGP("ctinfo = %u, skipping\n", ctinfo); -- return NF_ACCEPT; -- } -- -- /* not a complete TCP header? */ -- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4) { -- DEBUGP("tcplen = %u\n", tcplen); -- return NF_ACCEPT; -- } -- -- /* checksum invalid? */ -- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, -- csum_partial((char *) tcph, tcplen, 0))) { -- printk(KERN_NOTICE __FILE__ ": bad csum\n"); --// return NF_ACCEPT; -- } -- -- if (tcph->fin || tcph->rst) { -- DEBUGP("RST/FIN received, timeouting GRE\n"); -- /* can't do this after real newnat */ -- info->cstate = PPTP_CALL_NONE; -- -- /* untrack this call id, unexpect GRE packets */ -- pptp_timeout_related(ct); -- /* no need to call unexpect_related since master conn -- * dies anyway */ -- } -- -- -- pptph = (struct pptp_pkt_hdr *) ((void *) tcph + tcph->doff * 4); -- datalimit = (void *) pptph + datalen; -- -- /* not a full pptp packet header? */ -- if ((void *) pptph+sizeof(*pptph) >= datalimit) { -- DEBUGP("no full PPTP header, can't track\n"); -- return NF_ACCEPT; -- } -- -- /* if it's not a control message we can't do anything with it */ -- if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL || -- ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) { -- DEBUGP("not a control packet\n"); -- return NF_ACCEPT; -- } -- -- oldsstate = info->sstate; -- oldcstate = info->cstate; -- -- LOCK_BH(&ip_pptp_lock); -- -- if (dir == IP_CT_DIR_ORIGINAL) -- /* client -> server (PNS -> PAC) */ -- ret = pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo); -- else -- /* server -> client (PAC -> PNS) */ -- ret = pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo); -- DEBUGP("sstate: %d->%d, cstate: %d->%d\n", -- oldsstate, info->sstate, oldcstate, info->cstate); -- UNLOCK_BH(&ip_pptp_lock); -- -- return ret; --} -- --/* control protocol helper */ --static struct ip_conntrack_helper pptp = { -- { NULL, NULL }, -- "pptp", IP_CT_HELPER_F_REUSE_EXPECT, THIS_MODULE, 2, 0, -- { { 0, { tcp: { port: __constant_htons(PPTP_CONTROL_PORT) } } }, -- { 0, { 0 }, IPPROTO_TCP } }, -- { { 0, { tcp: { port: 0xffff } } }, -- { 0, { 0 }, 0xffff } }, -- conntrack_pptp_help }; -- --/* ip_conntrack_pptp initialization */ --static int __init init(void) --{ -- int retcode; -- -- DEBUGP(__FILE__ ": registering helper\n"); -- if ((retcode = ip_conntrack_helper_register(&pptp))) { -- printk(KERN_ERR "Unable to register conntrack application " -- "helper for pptp: %d\n", retcode); -- return -EIO; -- } -- -- return 0; --} -- --static void __exit fini(void) --{ -- ip_conntrack_helper_unregister(&pptp); --} -- --module_init(init); --module_exit(fini); -- --EXPORT_SYMBOL(ip_pptp_lock); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp_priv.h src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_pptp_priv.h ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp_priv.h 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_pptp_priv.h 1969-12-31 19:00:00.000000000 -0500 -@@ -1,24 +0,0 @@ --#ifndef _IP_CT_PPTP_PRIV_H --#define _IP_CT_PPTP_PRIV_H -- --/* PptpControlMessageType names */ --static const char *strMName[] = { -- "UNKNOWN_MESSAGE", -- "START_SESSION_REQUEST", -- "START_SESSION_REPLY", -- "STOP_SESSION_REQUEST", -- "STOP_SESSION_REPLY", -- "ECHO_REQUEST", -- "ECHO_REPLY", -- "OUT_CALL_REQUEST", -- "OUT_CALL_REPLY", -- "IN_CALL_REQUEST", -- "IN_CALL_REPLY", -- "IN_CALL_CONNECT", -- "CALL_CLEAR_REQUEST", -- "CALL_DISCONNECT_NOTIFY", -- "WAN_ERROR_NOTIFY", -- "SET_LINK_INFO" --}; -- --#endif -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_gre.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_gre.c ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_gre.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_gre.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,320 +0,0 @@ --/* -- * ip_conntrack_proto_gre.c - Version 1.11 -- * -- * Connection tracking protocol helper module for GRE. -- * -- * GRE is a generic encapsulation protocol, which is generally not very -- * suited for NAT, as it has no protocol-specific part as port numbers. -- * -- * It has an optional key field, which may help us distinguishing two -- * connections between the same two hosts. -- * -- * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 -- * -- * PPTP is built on top of a modified version of GRE, and has a mandatory -- * field called "CallID", which serves us for the same purpose as the key -- * field in plain GRE. -- * -- * Documentation about PPTP can be found in RFC 2637 -- * -- * (C) 2000-2002 by Harald Welte -- * -- * Development of this code funded by Astaro AG (http://www.astaro.com/) -- * -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include -- --#include -- --DECLARE_RWLOCK(ip_ct_gre_lock); --#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_ct_gre_lock) --#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_ct_gre_lock) -- --#include --#include --#include --#include -- --#include --#include -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Harald Welte "); --MODULE_DESCRIPTION("netfilter connection tracking protocol helper for GRE"); -- --/* shamelessly stolen from ip_conntrack_proto_udp.c */ --#define GRE_TIMEOUT (30*HZ) --#define GRE_STREAM_TIMEOUT (180*HZ) -- --#define DEBUGP(x, args...) --#define DUMP_TUPLE_GRE(x) -- --/* GRE KEYMAP HANDLING FUNCTIONS */ --static LIST_HEAD(gre_keymap_list); -- --static inline int gre_key_cmpfn(const struct ip_ct_gre_keymap *km, -- const struct ip_conntrack_tuple *t) --{ -- return ((km->tuple.src.ip == t->src.ip) && -- (km->tuple.dst.ip == t->dst.ip) && -- (km->tuple.dst.protonum == t->dst.protonum) && -- (km->tuple.dst.u.all == t->dst.u.all)); --} -- --/* look up the source key for a given tuple */ --static u_int32_t gre_keymap_lookup(struct ip_conntrack_tuple *t) --{ -- struct ip_ct_gre_keymap *km; -- u_int32_t key; -- -- READ_LOCK(&ip_ct_gre_lock); -- km = LIST_FIND(&gre_keymap_list, gre_key_cmpfn, -- struct ip_ct_gre_keymap *, t); -- if (!km) { -- READ_UNLOCK(&ip_ct_gre_lock); -- return 0; -- } -- -- key = km->tuple.src.u.gre.key; -- READ_UNLOCK(&ip_ct_gre_lock); -- -- return key; --} -- --/* add a single keymap entry, associate with specified expect */ --int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp, -- struct ip_conntrack_tuple *t, int reply) --{ -- struct ip_ct_gre_keymap *km; -- -- km = kmalloc(sizeof(*km), GFP_ATOMIC); -- if (!km) -- return -1; -- -- /* initializing list head should be sufficient */ -- memset(km, 0, sizeof(*km)); -- -- memcpy(&km->tuple, t, sizeof(*t)); -- km->master = exp; -- -- if (!reply) -- exp->proto.gre.keymap_orig = km; -- else -- exp->proto.gre.keymap_reply = km; -- -- DEBUGP("adding new entry %p: ", km); -- DUMP_TUPLE_GRE(&km->tuple); -- -- WRITE_LOCK(&ip_ct_gre_lock); -- list_append(&gre_keymap_list, km); -- WRITE_UNLOCK(&ip_ct_gre_lock); -- -- return 0; --} -- --/* change the tuple of a keymap entry (used by nat helper) */ --void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km, -- struct ip_conntrack_tuple *t) --{ -- DEBUGP("changing entry %p to: ", km); -- DUMP_TUPLE_GRE(t); -- -- WRITE_LOCK(&ip_ct_gre_lock); -- memcpy(&km->tuple, t, sizeof(km->tuple)); -- WRITE_UNLOCK(&ip_ct_gre_lock); --} -- -- --/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */ -- --/* invert gre part of tuple */ --static int gre_invert_tuple(struct ip_conntrack_tuple *tuple, -- const struct ip_conntrack_tuple *orig) --{ -- tuple->dst.u.gre.protocol = orig->dst.u.gre.protocol; -- tuple->dst.u.gre.version = orig->dst.u.gre.version; -- -- tuple->dst.u.gre.key = orig->src.u.gre.key; -- tuple->src.u.gre.key = orig->dst.u.gre.key; -- -- return 1; --} -- --/* gre hdr info to tuple */ --static int gre_pkt_to_tuple(const void *datah, size_t datalen, -- struct ip_conntrack_tuple *tuple) --{ -- struct gre_hdr *grehdr = (struct gre_hdr *) datah; -- struct gre_hdr_pptp *pgrehdr = (struct gre_hdr_pptp *) datah; -- u_int32_t srckey; -- -- /* core guarantees 8 protocol bytes, no need for size check */ -- -- tuple->dst.u.gre.version = grehdr->version; -- tuple->dst.u.gre.protocol = grehdr->protocol; -- -- switch (grehdr->version) { -- case GRE_VERSION_1701: -- if (!grehdr->key) { -- DEBUGP("Can't track GRE without key\n"); -- return 0; -- } -- tuple->dst.u.gre.key = *(gre_key(grehdr)); -- break; -- -- case GRE_VERSION_PPTP: -- if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) { -- DEBUGP("GRE_VERSION_PPTP but unknown proto\n"); -- return 0; -- } -- tuple->dst.u.gre.key = htonl(ntohs(pgrehdr->call_id)); -- break; -- -- default: -- printk(KERN_WARNING "unknown GRE version %hu\n", -- tuple->dst.u.gre.version); -- return 0; -- } -- -- srckey = gre_keymap_lookup(tuple); -- -- tuple->src.u.gre.key = srckey; -- -- return 1; --} -- --/* print gre part of tuple */ --static unsigned int gre_print_tuple(char *buffer, -- const struct ip_conntrack_tuple *tuple) --{ -- return sprintf(buffer, "version=%d protocol=0x%04x srckey=0x%x dstkey=0x%x ", -- tuple->dst.u.gre.version, -- ntohs(tuple->dst.u.gre.protocol), -- ntohl(tuple->src.u.gre.key), -- ntohl(tuple->dst.u.gre.key)); --} -- --/* print private data for conntrack */ --static unsigned int gre_print_conntrack(char *buffer, -- const struct ip_conntrack *ct) --{ -- return sprintf(buffer, "timeout=%u, stream_timeout=%u ", -- (ct->proto.gre.timeout / HZ), -- (ct->proto.gre.stream_timeout / HZ)); --} -- --/* Returns verdict for packet, and may modify conntrack */ --static int gre_packet(struct ip_conntrack *ct, -- struct iphdr *iph, size_t len, -- enum ip_conntrack_info conntrackinfo) --{ -- /* If we've seen traffic both ways, this is a GRE connection. -- * Extend timeout. */ -- if (ct->status & IPS_SEEN_REPLY) { -- ip_ct_refresh(ct, ct->proto.gre.stream_timeout); -- /* Also, more likely to be important, and not a probe. */ -- set_bit(IPS_ASSURED_BIT, &ct->status); -- } else -- ip_ct_refresh(ct, ct->proto.gre.timeout); -- -- return NF_ACCEPT; --} -- --/* Called when a new connection for this protocol found. */ --static int gre_new(struct ip_conntrack *ct, -- struct iphdr *iph, size_t len) --{ -- DEBUGP(": "); -- DUMP_TUPLE_GRE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); -- -- /* initialize to sane value. Ideally a conntrack helper -- * (e.g. in case of pptp) is increasing them */ -- ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT; -- ct->proto.gre.timeout = GRE_TIMEOUT; -- -- return 1; --} -- --/* Called when a conntrack entry has already been removed from the hashes -- * and is about to be deleted from memory */ --static void gre_destroy(struct ip_conntrack *ct) --{ -- struct ip_conntrack_expect *master = ct->master; -- -- DEBUGP(" entering\n"); -- -- if (!master) { -- DEBUGP("no master exp for ct %p\n", ct); -- return; -- } -- -- WRITE_LOCK(&ip_ct_gre_lock); -- if (master->proto.gre.keymap_orig) { -- DEBUGP("removing %p from list\n", master->proto.gre.keymap_orig); -- list_del(&master->proto.gre.keymap_orig->list); -- kfree(master->proto.gre.keymap_orig); -- } -- if (master->proto.gre.keymap_reply) { -- DEBUGP("removing %p from list\n", master->proto.gre.keymap_reply); -- list_del(&master->proto.gre.keymap_reply->list); -- kfree(master->proto.gre.keymap_reply); -- } -- WRITE_UNLOCK(&ip_ct_gre_lock); --} -- --/* protocol helper struct */ --static struct ip_conntrack_protocol gre = { { NULL, NULL }, IPPROTO_GRE, -- "gre", -- gre_pkt_to_tuple, -- gre_invert_tuple, -- gre_print_tuple, -- gre_print_conntrack, -- gre_packet, -- gre_new, -- gre_destroy, -- NULL, -- THIS_MODULE }; -- --/* ip_conntrack_proto_gre initialization */ --static int __init init(void) --{ -- int retcode; -- -- if ((retcode = ip_conntrack_protocol_register(&gre))) { -- printk(KERN_ERR "Unable to register conntrack protocol " -- "helper for gre: %d\n", retcode); -- return -EIO; -- } -- -- return 0; --} -- --static void __exit fini(void) --{ -- struct list_head *pos, *n; -- -- /* delete all keymap entries */ -- WRITE_LOCK(&ip_ct_gre_lock); -- list_for_each_safe(pos, n, &gre_keymap_list) { -- DEBUGP("deleting keymap %p\n", pos); -- list_del(pos); -- kfree(pos); -- } -- WRITE_UNLOCK(&ip_ct_gre_lock); -- -- ip_conntrack_protocol_unregister(&gre); --} -- --EXPORT_SYMBOL(ip_ct_gre_keymap_add); --EXPORT_SYMBOL(ip_ct_gre_keymap_change); -- --module_init(init); --module_exit(fini); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_tcp.c ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2003-08-12 07:33:45.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2004-05-09 04:13:03.000000000 -0400 -@@ -15,11 +15,17 @@ - #include - #include - -+#if 0 -+#define DEBUGP printk -+#else - #define DEBUGP(format, args...) -+#endif - - /* Protects conntrack->proto.tcp */ - static DECLARE_RWLOCK(tcp_lock); - -+/* FIXME: Examine ipfilter's timeouts and conntrack transitions more -+ closely. They're more complex. --RR */ - - /* Actually, I believe that neither ipmasq (where this code is stolen - from) nor ipfilter do it exactly right. A new conntrack machine taking -@@ -39,6 +45,25 @@ - "LISTEN" - }; - -+#define SECS *HZ -+#define MINS * 60 SECS -+#define HOURS * 60 MINS -+#define DAYS * 24 HOURS -+ -+ -+static unsigned long tcp_timeouts[] -+= { 30 MINS, /* TCP_CONNTRACK_NONE, */ -+ 5 DAYS, /* TCP_CONNTRACK_ESTABLISHED, */ -+ 2 MINS, /* TCP_CONNTRACK_SYN_SENT, */ -+ 60 SECS, /* TCP_CONNTRACK_SYN_RECV, */ -+ 2 MINS, /* TCP_CONNTRACK_FIN_WAIT, */ -+ 2 MINS, /* TCP_CONNTRACK_TIME_WAIT, */ -+ 10 SECS, /* TCP_CONNTRACK_CLOSE, */ -+ 60 SECS, /* TCP_CONNTRACK_CLOSE_WAIT, */ -+ 30 SECS, /* TCP_CONNTRACK_LAST_ACK, */ -+ 2 MINS, /* TCP_CONNTRACK_LISTEN, */ -+}; -+ - #define sNO TCP_CONNTRACK_NONE - #define sES TCP_CONNTRACK_ESTABLISHED - #define sSS TCP_CONNTRACK_SYN_SENT -@@ -161,13 +186,13 @@ - && tcph->syn && tcph->ack) - conntrack->proto.tcp.handshake_ack - = htonl(ntohl(tcph->seq) + 1); -+ WRITE_UNLOCK(&tcp_lock); - - /* If only reply is a RST, we can consider ourselves not to - have an established connection: this is a fairly common - problem case, so we can delete the conntrack - immediately. --RR */ - if (!(conntrack->status & IPS_SEEN_REPLY) && tcph->rst) { -- WRITE_UNLOCK(&tcp_lock); - if (del_timer(&conntrack->timeout)) - conntrack->timeout.function((unsigned long)conntrack); - } else { -@@ -178,9 +203,7 @@ - && tcph->ack_seq == conntrack->proto.tcp.handshake_ack) - set_bit(IPS_ASSURED_BIT, &conntrack->status); - -- WRITE_UNLOCK(&tcp_lock); -- ip_ct_refresh(conntrack, -- sysctl_ip_conntrack_tcp_timeouts[newconntrack]); -+ ip_ct_refresh(conntrack, tcp_timeouts[newconntrack]); - } - - return NF_ACCEPT; -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_udp.c ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2003-08-12 07:33:45.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2004-05-09 04:13:03.000000000 -0400 -@@ -5,7 +5,9 @@ - #include - #include - #include --#include -+ -+#define UDP_TIMEOUT (30*HZ) -+#define UDP_STREAM_TIMEOUT (180*HZ) - - static int udp_pkt_to_tuple(const void *datah, size_t datalen, - struct ip_conntrack_tuple *tuple) -@@ -50,13 +52,11 @@ - /* If we've seen traffic both ways, this is some kind of UDP - stream. Extend timeout. */ - if (conntrack->status & IPS_SEEN_REPLY) { -- ip_ct_refresh(conntrack, -- sysctl_ip_conntrack_udp_timeouts[UDP_STREAM_TIMEOUT]); -+ ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT); - /* Also, more likely to be important, and not a probe */ - set_bit(IPS_ASSURED_BIT, &conntrack->status); - } else -- ip_ct_refresh(conntrack, -- sysctl_ip_conntrack_udp_timeouts[UDP_TIMEOUT]); -+ ip_ct_refresh(conntrack, UDP_TIMEOUT); - - return NF_ACCEPT; - } -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_standalone.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_standalone.c ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-08-12 07:33:45.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-05-09 04:13:03.000000000 -0400 -@@ -27,7 +27,11 @@ - #include - #include - -+#if 0 -+#define DEBUGP printk -+#else - #define DEBUGP(format, args...) -+#endif - - struct module *ip_conntrack_module = THIS_MODULE; - MODULE_LICENSE("GPL"); -@@ -52,17 +56,12 @@ - return len; - } - -+/* FIXME: Don't print source proto part. --RR */ - static unsigned int - print_expect(char *buffer, const struct ip_conntrack_expect *expect) - { - unsigned int len; - -- if (!expect || !expect->expectant || !expect->expectant->helper) { -- DEBUGP("expect %x expect->expectant %x expect->expectant->helper %x\n", -- expect, expect->expectant, expect->expectant->helper); -- return 0; -- } -- - if (expect->expectant->helper->timeout) - len = sprintf(buffer, "EXPECTING: %lu ", - timer_pending(&expect->timeout) -@@ -294,6 +293,8 @@ - return ret; - } - -+/* FIXME: Allow NULL functions and sub in pointers to generic for -+ them. --RR */ - int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) - { - int ret = 0; -@@ -362,8 +363,6 @@ - EXPORT_SYMBOL(ip_ct_find_proto); - EXPORT_SYMBOL(__ip_ct_find_proto); - EXPORT_SYMBOL(ip_ct_find_helper); --EXPORT_SYMBOL(sysctl_ip_conntrack_tcp_timeouts); --EXPORT_SYMBOL(sysctl_ip_conntrack_udp_timeouts); - EXPORT_SYMBOL(ip_conntrack_expect_related); - EXPORT_SYMBOL(ip_conntrack_change_expect); - EXPORT_SYMBOL(ip_conntrack_unexpect_related); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_tftp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_tftp.c ---- src/linux/linux/net/ipv4/netfilter/ip_conntrack_tftp.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_tftp.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,126 +0,0 @@ --/* -- * Licensed under GNU GPL version 2 Copyright Magnus Boden -- * Version: 0.0.7 -- * -- * Thu 21 Mar 2002 Harald Welte -- * - port to newnat API -- * -- */ -- --#include --#include --#include -- --#include --#include --#include --#include -- --MODULE_AUTHOR("Magnus Boden "); --MODULE_DESCRIPTION("Netfilter connection tracking module for tftp"); --MODULE_LICENSE("GPL"); -- --#define MAX_PORTS 8 --static int ports[MAX_PORTS]; --static int ports_c = 0; --#ifdef MODULE_PARM --MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); --MODULE_PARM_DESC(ports, "port numbers of tftp servers"); --#endif -- --#define DEBUGP(format, args...) -- --static int tftp_help(const struct iphdr *iph, size_t len, -- struct ip_conntrack *ct, -- enum ip_conntrack_info ctinfo) --{ -- struct udphdr *udph = (void *)iph + iph->ihl * 4; -- struct tftphdr *tftph = (void *)udph + 8; -- struct ip_conntrack_expect exp; -- -- switch (ntohs(tftph->opcode)) { -- /* RRQ and WRQ works the same way */ -- case TFTP_OPCODE_READ: -- case TFTP_OPCODE_WRITE: -- DEBUGP(""); -- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); -- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); -- memset(&exp, 0, sizeof(exp)); -- -- exp.tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; -- exp.mask.src.ip = 0xffffffff; -- exp.mask.dst.ip = 0xffffffff; -- exp.mask.dst.u.udp.port = 0xffff; -- exp.mask.dst.protonum = 0xffff; -- exp.expectfn = NULL; -- -- DEBUGP("expect: "); -- DUMP_TUPLE(&exp.tuple); -- DUMP_TUPLE(&exp.mask); -- ip_conntrack_expect_related(ct, &exp); -- break; -- default: -- DEBUGP("Unknown opcode\n"); -- } -- return NF_ACCEPT; --} -- --static struct ip_conntrack_helper tftp[MAX_PORTS]; --static char tftp_names[MAX_PORTS][10]; -- --static void fini(void) --{ -- int i; -- -- for (i = 0 ; i < ports_c; i++) { -- DEBUGP("unregistering helper for port %d\n", -- ports[i]); -- ip_conntrack_helper_unregister(&tftp[i]); -- } --} -- --static int __init init(void) --{ -- int i, ret; -- char *tmpname; -- -- if (!ports[0]) -- ports[0]=TFTP_PORT; -- -- for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { -- /* Create helper structure */ -- memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper)); -- -- tftp[i].tuple.dst.protonum = IPPROTO_UDP; -- tftp[i].tuple.src.u.udp.port = htons(ports[i]); -- tftp[i].mask.dst.protonum = 0xFFFF; -- tftp[i].mask.src.u.udp.port = 0xFFFF; -- tftp[i].max_expected = 1; -- tftp[i].timeout = 0; -- tftp[i].flags = IP_CT_HELPER_F_REUSE_EXPECT; -- tftp[i].me = THIS_MODULE; -- tftp[i].help = tftp_help; -- -- tmpname = &tftp_names[i][0]; -- if (ports[i] == TFTP_PORT) -- sprintf(tmpname, "tftp"); -- else -- sprintf(tmpname, "tftp-%d", i); -- tftp[i].name = tmpname; -- -- DEBUGP("port #%d: %d\n", i, ports[i]); -- -- ret=ip_conntrack_helper_register(&tftp[i]); -- if (ret) { -- printk("ERROR registering helper for port %d\n", -- ports[i]); -- fini(); -- return(ret); -- } -- ports_c++; -- } -- return(0); --} -- --module_init(init); --module_exit(fini); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_core.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_core.c ---- src/linux/linux/net/ipv4/netfilter/ip_nat_core.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_core.c 2004-05-09 04:13:03.000000000 -0400 -@@ -31,7 +31,11 @@ - #include - #include - -+#if 0 -+#define DEBUGP printk -+#else - #define DEBUGP(format, args...) -+#endif - - DECLARE_RWLOCK(ip_nat_lock); - DECLARE_RWLOCK_EXTERN(ip_conntrack_lock); -@@ -207,6 +211,7 @@ - { - struct rtable *rt; - -+ /* FIXME: IPTOS_TOS(iph->tos) --RR */ - if (ip_route_output(&rt, var_ip, 0, 0, 0) != 0) { - DEBUGP("do_extra_mangle: Can't get route to %u.%u.%u.%u\n", - NIPQUAD(var_ip)); -@@ -429,7 +434,7 @@ - *tuple = *orig_tuple; - while ((rptr = find_best_ips_proto_fast(tuple, mr, conntrack, hooknum)) - != NULL) { -- DEBUGP("Found best for "); DUMP_TUPLE_RAW(tuple); -+ DEBUGP("Found best for "); DUMP_TUPLE(tuple); - /* 3) The per-protocol part of the manip is made to - map into the range to make a unique tuple. */ - -@@ -529,6 +534,31 @@ - invert_tuplepr(&orig_tp, - &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple); - -+#if 0 -+ { -+ unsigned int i; -+ -+ DEBUGP("Hook %u (%s), ", hooknum, -+ HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST"); -+ DUMP_TUPLE(&orig_tp); -+ DEBUGP("Range %p: ", mr); -+ for (i = 0; i < mr->rangesize; i++) { -+ DEBUGP("%u:%s%s%s %u.%u.%u.%u - %u.%u.%u.%u %u - %u\n", -+ i, -+ (mr->range[i].flags & IP_NAT_RANGE_MAP_IPS) -+ ? " MAP_IPS" : "", -+ (mr->range[i].flags -+ & IP_NAT_RANGE_PROTO_SPECIFIED) -+ ? " PROTO_SPECIFIED" : "", -+ (mr->range[i].flags & IP_NAT_RANGE_FULL) -+ ? " FULL" : "", -+ NIPQUAD(mr->range[i].min_ip), -+ NIPQUAD(mr->range[i].max_ip), -+ mr->range[i].min.all, -+ mr->range[i].max.all); -+ } -+ } -+#endif - - do { - if (!get_unique_tuple(&new_tuple, &orig_tp, mr, conntrack, -@@ -538,6 +568,15 @@ - return NF_DROP; - } - -+#if 0 -+ DEBUGP("Hook %u (%s) %p\n", hooknum, -+ HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST", -+ conntrack); -+ DEBUGP("Original: "); -+ DUMP_TUPLE(&orig_tp); -+ DEBUGP("New: "); -+ DUMP_TUPLE(&new_tuple); -+#endif - - /* We now have two tuples (SRCIP/SRCPT/DSTIP/DSTPT): - the original (A/B/C/D') and the mangled one (E/F/G/H'). -@@ -554,6 +593,8 @@ - If fail this race (reply tuple now used), repeat. */ - } while (!ip_conntrack_alter_reply(conntrack, &reply)); - -+ /* FIXME: We can simply used existing conntrack reply tuple -+ here --RR */ - /* Create inverse of original: C/D/A/B' */ - invert_tuplepr(&inv_tuple, &orig_tp); - -@@ -678,6 +719,17 @@ - iph->check); - iph->daddr = manip->ip; - } -+#if 0 -+ if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) -+ DEBUGP("IP: checksum on packet bad.\n"); -+ -+ if (proto == IPPROTO_TCP) { -+ void *th = (u_int32_t *)iph + iph->ihl; -+ if (tcp_v4_check(th, len - 4*iph->ihl, iph->saddr, iph->daddr, -+ csum_partial((char *)th, len-4*iph->ihl, 0))) -+ DEBUGP("TCP: checksum on packet bad\n"); -+ } -+#endif - } - - static inline int exp_for_packet(struct ip_conntrack_expect *exp, -@@ -765,6 +817,7 @@ - continue; - - if (exp_for_packet(exp, pskb)) { -+ /* FIXME: May be true multiple times in the case of UDP!! */ - DEBUGP("calling nat helper (exp=%p) for packet\n", - exp); - ret = helper->help(ct, exp, info, ctinfo, -@@ -926,6 +979,7 @@ - INIT_LIST_HEAD(&byipsproto[i]); - } - -+ /* FIXME: Man, this is a hack. */ - IP_NF_ASSERT(ip_conntrack_destroyed == NULL); - ip_conntrack_destroyed = &ip_nat_cleanup_conntrack; - -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_h323.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_h323.c ---- src/linux/linux/net/ipv4/netfilter/ip_nat_h323.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_h323.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,403 +0,0 @@ --/* -- * H.323 'brute force' extension for NAT alteration. -- * Jozsef Kadlecsik -- * -- * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project. -- * (http://www.coritel.it/projects/sofia/nat.html) -- * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind' -- * the unregistered helpers to the conntrack entries. -- */ -- -- --#include --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include --#include -- --MODULE_AUTHOR("Jozsef Kadlecsik "); --MODULE_DESCRIPTION("H.323 'brute force' connection tracking module"); --MODULE_LICENSE("GPL"); -- --DECLARE_LOCK_EXTERN(ip_h323_lock); --struct module *ip_nat_h323 = THIS_MODULE; -- --#define DEBUGP(format, args...) -- -- --static unsigned int --h225_nat_expected(struct sk_buff **pskb, -- unsigned int hooknum, -- struct ip_conntrack *ct, -- struct ip_nat_info *info); -- --static unsigned int h225_nat_help(struct ip_conntrack *ct, -- struct ip_conntrack_expect *exp, -- struct ip_nat_info *info, -- enum ip_conntrack_info ctinfo, -- unsigned int hooknum, -- struct sk_buff **pskb); -- --static struct ip_nat_helper h245 = -- { { NULL, NULL }, -- "H.245", /* name */ -- 0, /* flags */ -- NULL, /* module */ -- { { 0, { 0 } }, /* tuple */ -- { 0, { 0 }, IPPROTO_TCP } }, -- { { 0, { 0xFFFF } }, /* mask */ -- { 0, { 0 }, 0xFFFF } }, -- h225_nat_help, /* helper */ -- h225_nat_expected /* expectfn */ -- }; -- --static unsigned int --h225_nat_expected(struct sk_buff **pskb, -- unsigned int hooknum, -- struct ip_conntrack *ct, -- struct ip_nat_info *info) --{ -- struct ip_nat_multi_range mr; -- u_int32_t newdstip, newsrcip, newip; -- u_int16_t port; -- struct ip_ct_h225_expect *exp_info; -- struct ip_ct_h225_master *master_info; -- struct ip_conntrack *master = master_ct(ct); -- unsigned int is_h225, ret; -- -- IP_NF_ASSERT(info); -- IP_NF_ASSERT(master); -- -- IP_NF_ASSERT(!(info->initialized & (1<master->expectant->help.ct_h225_info; -- exp_info = &ct->master->help.exp_h225_info; -- -- LOCK_BH(&ip_h323_lock); -- -- DEBUGP("master: "); -- DUMP_TUPLE(&master->tuplehash[IP_CT_DIR_ORIGINAL].tuple); -- DUMP_TUPLE(&master->tuplehash[IP_CT_DIR_REPLY].tuple); -- DEBUGP("conntrack: "); -- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); -- if (exp_info->dir == IP_CT_DIR_ORIGINAL) { -- /* Make connection go to the client. */ -- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; -- newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; -- DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to client)\n", -- NIPQUAD(newsrcip), NIPQUAD(newdstip)); -- } else { -- /* Make the connection go to the server */ -- newdstip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; -- newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -- DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to server)\n", -- NIPQUAD(newsrcip), NIPQUAD(newdstip)); -- } -- port = exp_info->port; -- is_h225 = master_info->is_h225 == H225_PORT; -- UNLOCK_BH(&ip_h323_lock); -- -- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) -- newip = newsrcip; -- else -- newip = newdstip; -- -- DEBUGP("h225_nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip)); -- -- mr.rangesize = 1; -- /* We don't want to manip the per-protocol, just the IPs... */ -- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; -- mr.range[0].min_ip = mr.range[0].max_ip = newip; -- -- /* ... unless we're doing a MANIP_DST, in which case, make -- sure we map to the correct port */ -- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { -- mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; -- mr.range[0].min = mr.range[0].max -- = ((union ip_conntrack_manip_proto) -- { port }); -- } -- -- ret = ip_nat_setup_info(ct, &mr, hooknum); -- -- if (is_h225) { -- DEBUGP("h225_nat_expected: H.225, setting NAT helper for %p\n", ct); -- /* NAT expectfn called with ip_nat_lock write-locked */ -- info->helper = &h245; -- } -- return ret; --} -- --static int h323_signal_address_fixup(struct ip_conntrack *ct, -- struct sk_buff **pskb, -- enum ip_conntrack_info ctinfo) --{ -- struct iphdr *iph = (*pskb)->nh.iph; -- struct tcphdr *tcph = (void *)iph + iph->ihl*4; -- unsigned char *data; -- u_int32_t tcplen = (*pskb)->len - iph->ihl*4; -- u_int32_t datalen = tcplen - tcph->doff*4; -- struct ip_ct_h225_master *info = &ct->help.ct_h225_info; -- u_int32_t newip; -- u_int16_t port; -- u_int8_t buffer[6]; -- int i; -- -- MUST_BE_LOCKED(&ip_h323_lock); -- -- DEBUGP("h323_signal_address_fixup: %s %s\n", -- between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen) -- ? "yes" : "no", -- between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen) -- ? "yes" : "no"); -- if (!(between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen) -- || between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen))) -- return 1; -- -- DEBUGP("h323_signal_address_fixup: offsets %u + 6 and %u + 6 in %u\n", -- info->offset[IP_CT_DIR_ORIGINAL], -- info->offset[IP_CT_DIR_REPLY], -- tcplen); -- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); -- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); -- -- for (i = 0; i < IP_CT_DIR_MAX; i++) { -- DEBUGP("h323_signal_address_fixup: %s %s\n", -- info->dir == IP_CT_DIR_ORIGINAL ? "original" : "reply", -- i == IP_CT_DIR_ORIGINAL ? "caller" : "callee"); -- if (!between(info->seq[i], ntohl(tcph->seq), -- ntohl(tcph->seq) + datalen)) -- continue; -- if (!between(info->seq[i] + 6, ntohl(tcph->seq), -- ntohl(tcph->seq) + datalen)) { -- /* Partial retransmisison. It's a cracker being funky. */ -- if (net_ratelimit()) { -- printk("H.323_NAT: partial packet %u/6 in %u/%u\n", -- info->seq[i], -- ntohl(tcph->seq), -- ntohl(tcph->seq) + datalen); -- } -- return 0; -- } -- -- /* Change address inside packet to match way we're mapping -- this connection. */ -- if (i == IP_CT_DIR_ORIGINAL) { -- newip = ct->tuplehash[!info->dir].tuple.dst.ip; -- port = ct->tuplehash[!info->dir].tuple.dst.u.tcp.port; -- } else { -- newip = ct->tuplehash[!info->dir].tuple.src.ip; -- port = ct->tuplehash[!info->dir].tuple.src.u.tcp.port; -- } -- -- data = (char *) tcph + tcph->doff * 4 + info->offset[i]; -- -- DEBUGP("h323_signal_address_fixup: orig %s IP:port %u.%u.%u.%u:%u\n", -- i == IP_CT_DIR_ORIGINAL ? "source" : "dest ", -- data[0], data[1], data[2], data[3], -- (data[4] << 8 | data[5])); -- -- /* Modify the packet */ -- memcpy(buffer, &newip, 4); -- memcpy(buffer + 4, &port, 2); -- if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, info->offset[i], -- 6, buffer, 6)) -- return 0; -- -- DEBUGP("h323_signal_address_fixup: new %s IP:port %u.%u.%u.%u:%u\n", -- i == IP_CT_DIR_ORIGINAL ? "source" : "dest ", -- data[0], data[1], data[2], data[3], -- (data[4] << 8 | data[5])); -- } -- -- return 1; --} -- --static int h323_data_fixup(struct ip_ct_h225_expect *info, -- struct ip_conntrack *ct, -- struct sk_buff **pskb, -- enum ip_conntrack_info ctinfo, -- struct ip_conntrack_expect *expect) --{ -- u_int32_t newip; -- u_int16_t port; -- u_int8_t buffer[6]; -- struct ip_conntrack_tuple newtuple; -- struct iphdr *iph = (*pskb)->nh.iph; -- struct tcphdr *tcph = (void *)iph + iph->ihl*4; -- unsigned char *data; -- u_int32_t tcplen = (*pskb)->len - iph->ihl*4; -- struct ip_ct_h225_master *master_info = &ct->help.ct_h225_info; -- int is_h225; -- -- MUST_BE_LOCKED(&ip_h323_lock); -- DEBUGP("h323_data_fixup: offset %u + 6 in %u\n", info->offset, tcplen); -- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); -- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); -- -- if (!between(expect->seq + 6, ntohl(tcph->seq), -- ntohl(tcph->seq) + tcplen - tcph->doff * 4)) { -- /* Partial retransmisison. It's a cracker being funky. */ -- if (net_ratelimit()) { -- printk("H.323_NAT: partial packet %u/6 in %u/%u\n", -- expect->seq, -- ntohl(tcph->seq), -- ntohl(tcph->seq) + tcplen - tcph->doff * 4); -- } -- return 0; -- } -- -- /* Change address inside packet to match way we're mapping -- this connection. */ -- if (info->dir == IP_CT_DIR_REPLY) { -- /* Must be where client thinks server is */ -- newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; -- /* Expect something from client->server */ -- newtuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; -- newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; -- } else { -- /* Must be where server thinks client is */ -- newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -- /* Expect something from server->client */ -- newtuple.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; -- newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -- } -- -- is_h225 = (master_info->is_h225 == H225_PORT); -- -- if (is_h225) { -- newtuple.dst.protonum = IPPROTO_TCP; -- newtuple.src.u.tcp.port = expect->tuple.src.u.tcp.port; -- } else { -- newtuple.dst.protonum = IPPROTO_UDP; -- newtuple.src.u.udp.port = expect->tuple.src.u.udp.port; -- } -- -- /* Try to get same port: if not, try to change it. */ -- for (port = ntohs(info->port); port != 0; port++) { -- if (is_h225) -- newtuple.dst.u.tcp.port = htons(port); -- else -- newtuple.dst.u.udp.port = htons(port); -- -- if (ip_conntrack_change_expect(expect, &newtuple) == 0) -- break; -- } -- if (port == 0) { -- DEBUGP("h323_data_fixup: no free port found!\n"); -- return 0; -- } -- -- port = htons(port); -- -- data = (char *) tcph + tcph->doff * 4 + info->offset; -- -- DEBUGP("h323_data_fixup: orig IP:port %u.%u.%u.%u:%u\n", -- data[0], data[1], data[2], data[3], -- (data[4] << 8 | data[5])); -- -- /* Modify the packet */ -- memcpy(buffer, &newip, 4); -- memcpy(buffer + 4, &port, 2); -- if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, info->offset, -- 6, buffer, 6)) -- return 0; -- -- DEBUGP("h323_data_fixup: new IP:port %u.%u.%u.%u:%u\n", -- data[0], data[1], data[2], data[3], -- (data[4] << 8 | data[5])); -- -- return 1; --} -- --static unsigned int h225_nat_help(struct ip_conntrack *ct, -- struct ip_conntrack_expect *exp, -- struct ip_nat_info *info, -- enum ip_conntrack_info ctinfo, -- unsigned int hooknum, -- struct sk_buff **pskb) --{ -- int dir; -- struct ip_ct_h225_expect *exp_info; -- -- /* Only mangle things once: original direction in POST_ROUTING -- and reply direction on PRE_ROUTING. */ -- dir = CTINFO2DIR(ctinfo); -- DEBUGP("nat_h323: dir %s at hook %s\n", -- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", -- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" -- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" -- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); -- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) -- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { -- DEBUGP("nat_h323: Not touching dir %s at hook %s\n", -- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", -- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" -- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" -- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); -- return NF_ACCEPT; -- } -- -- if (!exp) { -- LOCK_BH(&ip_h323_lock); -- if (!h323_signal_address_fixup(ct, pskb, ctinfo)) { -- UNLOCK_BH(&ip_h323_lock); -- return NF_DROP; -- } -- UNLOCK_BH(&ip_h323_lock); -- return NF_ACCEPT; -- } -- -- exp_info = &exp->help.exp_h225_info; -- -- LOCK_BH(&ip_h323_lock); -- if (!h323_data_fixup(exp_info, ct, pskb, ctinfo, exp)) { -- UNLOCK_BH(&ip_h323_lock); -- return NF_DROP; -- } -- UNLOCK_BH(&ip_h323_lock); -- -- return NF_ACCEPT; --} -- --static struct ip_nat_helper h225 = -- { { NULL, NULL }, -- "H.225", /* name */ -- IP_NAT_HELPER_F_ALWAYS, /* flags */ -- THIS_MODULE, /* module */ -- { { 0, { __constant_htons(H225_PORT) } }, /* tuple */ -- { 0, { 0 }, IPPROTO_TCP } }, -- { { 0, { 0xFFFF } }, /* mask */ -- { 0, { 0 }, 0xFFFF } }, -- h225_nat_help, /* helper */ -- h225_nat_expected /* expectfn */ -- }; -- --static int __init init(void) --{ -- int ret; -- -- ret = ip_nat_helper_register(&h225); -- -- if (ret != 0) -- printk("ip_nat_h323: cannot initialize the module!\n"); -- -- return ret; --} -- --static void __exit fini(void) --{ -- ip_nat_helper_unregister(&h225); --} -- --module_init(init); --module_exit(fini); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_helper.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_helper.c ---- src/linux/linux/net/ipv4/netfilter/ip_nat_helper.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_helper.c 2004-05-09 04:13:03.000000000 -0400 -@@ -8,9 +8,6 @@ - * - add support for SACK adjustment - * 14 Mar 2002 Harald Welte : - * - merge SACK support into newnat API -- * 16 Aug 2002 Brian J. Murrell : -- * - make ip_nat_resize_packet more generic (TCP and UDP) -- * - add ip_nat_mangle_udp_packet - */ - #include - #include -@@ -25,7 +22,6 @@ - #include - #include - #include --#include - - #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) - #define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) -@@ -38,8 +34,13 @@ - #include - #include - -+#if 0 -+#define DEBUGP printk -+#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos); -+#else - #define DEBUGP(format, args...) - #define DUMP_OFFSET(x) -+#endif - - DECLARE_LOCK(ip_nat_seqofs_lock); - -@@ -50,12 +51,18 @@ - int new_size) - { - struct iphdr *iph; -+ struct tcphdr *tcph; -+ void *data; - int dir; - struct ip_nat_seq *this_way, *other_way; - - DEBUGP("ip_nat_resize_packet: old_size = %u, new_size = %u\n", - (*skb)->len, new_size); - -+ iph = (*skb)->nh.iph; -+ tcph = (void *)iph + iph->ihl*4; -+ data = (void *)tcph + tcph->doff*4; -+ - dir = CTINFO2DIR(ctinfo); - - this_way = &ct->nat.info.seq[dir]; -@@ -77,9 +84,8 @@ - } - - iph = (*skb)->nh.iph; -- if (iph->protocol == IPPROTO_TCP) { -- struct tcphdr *tcph = (void *)iph + iph->ihl*4; -- void *data = (void *)tcph + tcph->doff*4; -+ tcph = (void *)iph + iph->ihl*4; -+ data = (void *)tcph + tcph->doff*4; - - DEBUGP("ip_nat_resize_packet: Seq_offset before: "); - DUMP_OFFSET(this_way); -@@ -95,20 +101,25 @@ - this_way->correction_pos = ntohl(tcph->seq); - this_way->offset_before = this_way->offset_after; - this_way->offset_after = (int32_t) -- this_way->offset_before + new_size - -- (*skb)->len; -+ this_way->offset_before + new_size - (*skb)->len; - } - - UNLOCK_BH(&ip_nat_seqofs_lock); - - DEBUGP("ip_nat_resize_packet: Seq_offset after: "); - DUMP_OFFSET(this_way); -- } - - return 1; - } - - -+/* Generic function for mangling variable-length address changes inside -+ * NATed connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX command in FTP). -+ * -+ * Takes care about all the nasty sequence number changes, checksumming, -+ * skb enlargement, ... -+ * -+ * */ - int - ip_nat_mangle_tcp_packet(struct sk_buff **skb, - struct ip_conntrack *ct, -@@ -163,7 +174,6 @@ - tcph = (void *)iph + iph->ihl*4; - data = (void *)tcph + tcph->doff*4; - -- if (rep_len != match_len) - /* move post-replacement */ - memmove(data + match_offset + rep_len, - data + match_offset + match_len, -@@ -198,104 +208,6 @@ - return 1; - } - --int --ip_nat_mangle_udp_packet(struct sk_buff **skb, -- struct ip_conntrack *ct, -- enum ip_conntrack_info ctinfo, -- unsigned int match_offset, -- unsigned int match_len, -- char *rep_buffer, -- unsigned int rep_len) --{ -- struct iphdr *iph = (*skb)->nh.iph; -- struct udphdr *udph = (void *)iph + iph->ihl * 4; -- unsigned char *data; -- u_int32_t udplen, newlen, newudplen; -- -- udplen = (*skb)->len - iph->ihl*4; -- newudplen = udplen - match_len + rep_len; -- newlen = iph->ihl*4 + newudplen; -- -- if (newlen > 65535) { -- if (net_ratelimit()) -- printk("ip_nat_mangle_udp_packet: nat'ed packet " -- "exceeds maximum packet size\n"); -- return 0; -- } -- -- if ((*skb)->len != newlen) { -- if (!ip_nat_resize_packet(skb, ct, ctinfo, newlen)) { -- printk("resize_packet failed!!\n"); -- return 0; -- } -- } -- -- /* Alexey says: if a hook changes _data_ ... it can break -- original packet sitting in tcp queue and this is fatal */ -- if (skb_cloned(*skb)) { -- struct sk_buff *nskb = skb_copy(*skb, GFP_ATOMIC); -- if (!nskb) { -- if (net_ratelimit()) -- printk("Out of memory cloning TCP packet\n"); -- return 0; -- } -- /* Rest of kernel will get very unhappy if we pass it -- a suddenly-orphaned skbuff */ -- if ((*skb)->sk) -- skb_set_owner_w(nskb, (*skb)->sk); -- kfree_skb(*skb); -- *skb = nskb; -- } -- -- /* skb may be copied !! */ -- iph = (*skb)->nh.iph; -- udph = (void *)iph + iph->ihl*4; -- data = (void *)udph + sizeof(struct udphdr); -- -- if (rep_len != match_len) -- /* move post-replacement */ -- memmove(data + match_offset + rep_len, -- data + match_offset + match_len, -- (*skb)->tail - (data + match_offset + match_len)); -- -- /* insert data from buffer */ -- memcpy(data + match_offset, rep_buffer, rep_len); -- -- /* update skb info */ -- if (newlen > (*skb)->len) { -- DEBUGP("ip_nat_mangle_udp_packet: Extending packet by " -- "%u to %u bytes\n", newlen - (*skb)->len, newlen); -- skb_put(*skb, newlen - (*skb)->len); -- } else { -- DEBUGP("ip_nat_mangle_udp_packet: Shrinking packet from " -- "%u to %u bytes\n", (*skb)->len, newlen); -- skb_trim(*skb, newlen); -- } -- -- /* update the length of the UDP and IP packets to the new values*/ -- udph->len = htons((*skb)->len - iph->ihl*4); -- iph->tot_len = htons(newlen); -- -- /* fix udp checksum if udp checksum was previously calculated */ -- if ((*skb)->csum != 0) { -- (*skb)->csum = csum_partial((char *)udph + -- sizeof(struct udphdr), -- newudplen - sizeof(struct udphdr), -- 0); -- -- udph->check = 0; -- udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, -- newudplen, IPPROTO_UDP, -- csum_partial((char *)udph, -- sizeof(struct udphdr), -- (*skb)->csum)); -- } -- -- ip_send_check(iph); -- -- return 1; --} -- - /* Adjust one found SACK option including checksum correction */ - static void - sack_adjust(struct tcphdr *tcph, -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_mms.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_mms.c ---- src/linux/linux/net/ipv4/netfilter/ip_nat_mms.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_mms.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,330 +0,0 @@ --/* MMS extension for TCP NAT alteration. -- * (C) 2002 by Filip Sneppe -- * based on ip_nat_ftp.c and ip_nat_irc.c -- * -- * ip_nat_mms.c v0.3 2002-09-22 -- * -- * This program is free software; you can redistribute it and/or -- * modify it under the terms of the GNU General Public License -- * as published by the Free Software Foundation; either version -- * 2 of the License, or (at your option) any later version. -- * -- * Module load syntax: -- * insmod ip_nat_mms.o ports=port1,port2,...port -- * -- * Please give the ports of all MMS servers You wish to connect to. -- * If you don't specify ports, the default will be TCP port 1755. -- * -- * More info on MMS protocol, firewalls and NAT: -- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp -- * http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp -- * -- * The SDP project people are reverse-engineering MMS: -- * http://get.to/sdp -- */ -- -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define DEBUGP(format, args...) --#define DUMP_BYTES(address, counter) -- --#define MAX_PORTS 8 --static int ports[MAX_PORTS]; --static int ports_c = 0; -- --#ifdef MODULE_PARM --MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); --#endif -- --MODULE_AUTHOR("Filip Sneppe "); --MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) NAT module"); --MODULE_LICENSE("GPL"); -- --DECLARE_LOCK_EXTERN(ip_mms_lock); -- -- --static int mms_data_fixup(const struct ip_ct_mms_expect *ct_mms_info, -- struct ip_conntrack *ct, -- struct sk_buff **pskb, -- enum ip_conntrack_info ctinfo, -- struct ip_conntrack_expect *expect) --{ -- u_int32_t newip; -- struct ip_conntrack_tuple t; -- struct iphdr *iph = (*pskb)->nh.iph; -- struct tcphdr *tcph = (void *) iph + iph->ihl * 4; -- char *data = (char *)tcph + tcph->doff * 4; -- int i, j, k, port; -- u_int16_t mms_proto; -- -- u_int32_t *mms_chunkLenLV = (u_int32_t *)(data + MMS_SRV_CHUNKLENLV_OFFSET); -- u_int32_t *mms_chunkLenLM = (u_int32_t *)(data + MMS_SRV_CHUNKLENLM_OFFSET); -- u_int32_t *mms_messageLength = (u_int32_t *)(data + MMS_SRV_MESSAGELENGTH_OFFSET); -- -- int zero_padding; -- -- char buffer[28]; /* "\\255.255.255.255\UDP\65635" * 2 (for unicode) */ -- char unicode_buffer[75]; /* 27*2 (unicode) + 20 + 1 */ -- char proto_string[6]; -- -- MUST_BE_LOCKED(&ip_mms_lock); -- -- /* what was the protocol again ? */ -- mms_proto = expect->tuple.dst.protonum; -- sprintf(proto_string, "%u", mms_proto); -- -- DEBUGP("ip_nat_mms: mms_data_fixup: info (seq %u + %u) in %u, proto %s\n", -- expect->seq, ct_mms_info->len, ntohl(tcph->seq), -- mms_proto == IPPROTO_UDP ? "UDP" -- : mms_proto == IPPROTO_TCP ? "TCP":proto_string); -- -- newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -- -- /* Alter conntrack's expectations. */ -- t = expect->tuple; -- t.dst.ip = newip; -- for (port = ct_mms_info->port; port != 0; port++) { -- t.dst.u.tcp.port = htons(port); -- if (ip_conntrack_change_expect(expect, &t) == 0) { -- DEBUGP("ip_nat_mms: mms_data_fixup: using port %d\n", port); -- break; -- } -- } -- -- if(port == 0) -- return 0; -- -- sprintf(buffer, "\\\\%u.%u.%u.%u\\%s\\%u", -- NIPQUAD(newip), -- expect->tuple.dst.protonum == IPPROTO_UDP ? "UDP" -- : expect->tuple.dst.protonum == IPPROTO_TCP ? "TCP":proto_string, -- port); -- DEBUGP("ip_nat_mms: new unicode string=%s\n", buffer); -- -- memset(unicode_buffer, 0, sizeof(char)*75); -- -- for (i=0; ipadding, ct_mms_info->len); -- DEBUGP("ip_nat_mms: mms_data_fixup: offset: %u\n", MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len); -- DUMP_BYTES(data+MMS_SRV_UNICODE_STRING_OFFSET, 60); -- -- /* add end of packet to it */ -- for (j=0; jpadding; ++j) { -- DEBUGP("ip_nat_mms: mms_data_fixup: i=%u j=%u byte=%u\n", -- i, j, (u8)*(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j)); -- *(unicode_buffer+i*2+j) = *(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j); -- } -- -- /* pad with zeroes at the end ? see explanation of weird math below */ -- zero_padding = (8-(strlen(buffer)*2 + ct_mms_info->padding + 4)%8)%8; -- for (k=0; k chunkLenLV=%u chunkLenLM=%u messageLength=%u\n", -- *mms_chunkLenLV, *mms_chunkLenLM, *mms_messageLength); -- -- /* explanation, before I forget what I did: -- strlen(buffer)*2 + ct_mms_info->padding + 4 must be divisable by 8; -- divide by 8 and add 3 to compute the mms_chunkLenLM field, -- but note that things may have to be padded with zeroes to align by 8 -- bytes, hence we add 7 and divide by 8 to get the correct length */ -- *mms_chunkLenLM = (u_int32_t) (3+(strlen(buffer)*2+ct_mms_info->padding+11)/8); -- *mms_chunkLenLV = *mms_chunkLenLM+2; -- *mms_messageLength = *mms_chunkLenLV*8; -- -- DEBUGP("ip_nat_mms: modified=> chunkLenLV=%u chunkLenLM=%u messageLength=%u\n", -- *mms_chunkLenLV, *mms_chunkLenLM, *mms_messageLength); -- -- ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, -- expect->seq - ntohl(tcph->seq), -- ct_mms_info->len + ct_mms_info->padding, unicode_buffer, -- strlen(buffer)*2 + ct_mms_info->padding + zero_padding); -- DUMP_BYTES(unicode_buffer, 60); -- -- return 1; --} -- --static unsigned int --mms_nat_expected(struct sk_buff **pskb, -- unsigned int hooknum, -- struct ip_conntrack *ct, -- struct ip_nat_info *info) --{ -- struct ip_nat_multi_range mr; -- u_int32_t newdstip, newsrcip, newip; -- -- struct ip_conntrack *master = master_ct(ct); -- -- IP_NF_ASSERT(info); -- IP_NF_ASSERT(master); -- -- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); -- -- DEBUGP("ip_nat_mms: mms_nat_expected: We have a connection!\n"); -- -- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; -- newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; -- DEBUGP("ip_nat_mms: mms_nat_expected: hook %s: newsrc->newdst %u.%u.%u.%u->%u.%u.%u.%u\n", -- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" -- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" -- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???", -- NIPQUAD(newsrcip), NIPQUAD(newdstip)); -- -- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) -- newip = newsrcip; -- else -- newip = newdstip; -- -- DEBUGP("ip_nat_mms: mms_nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip)); -- -- mr.rangesize = 1; -- /* We don't want to manip the per-protocol, just the IPs. */ -- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; -- mr.range[0].min_ip = mr.range[0].max_ip = newip; -- -- return ip_nat_setup_info(ct, &mr, hooknum); --} -- -- --static unsigned int mms_nat_help(struct ip_conntrack *ct, -- struct ip_conntrack_expect *exp, -- struct ip_nat_info *info, -- enum ip_conntrack_info ctinfo, -- unsigned int hooknum, -- struct sk_buff **pskb) --{ -- struct iphdr *iph = (*pskb)->nh.iph; -- struct tcphdr *tcph = (void *) iph + iph->ihl * 4; -- unsigned int datalen; -- int dir; -- struct ip_ct_mms_expect *ct_mms_info; -- -- if (!exp) -- DEBUGP("ip_nat_mms: no exp!!"); -- -- ct_mms_info = &exp->help.exp_mms_info; -- -- /* Only mangle things once: original direction in POST_ROUTING -- and reply direction on PRE_ROUTING. */ -- dir = CTINFO2DIR(ctinfo); -- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) -- ||(hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { -- DEBUGP("ip_nat_mms: mms_nat_help: not touching dir %s at hook %s\n", -- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", -- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" -- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" -- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); -- return NF_ACCEPT; -- } -- DEBUGP("ip_nat_mms: mms_nat_help: beyond not touching (dir %s at hook %s)\n", -- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", -- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" -- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" -- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); -- -- datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4; -- -- DEBUGP("ip_nat_mms: mms_nat_help: %u+%u=%u %u %u\n", exp->seq, ct_mms_info->len, -- exp->seq + ct_mms_info->len, -- ntohl(tcph->seq), -- ntohl(tcph->seq) + datalen); -- -- LOCK_BH(&ip_mms_lock); -- /* Check wether the whole IP/proto/port pattern is carried in the payload */ -- if (between(exp->seq + ct_mms_info->len, -- ntohl(tcph->seq), -- ntohl(tcph->seq) + datalen)) { -- if (!mms_data_fixup(ct_mms_info, ct, pskb, ctinfo, exp)) { -- UNLOCK_BH(&ip_mms_lock); -- return NF_DROP; -- } -- } else { -- /* Half a match? This means a partial retransmisison. -- It's a cracker being funky. */ -- if (net_ratelimit()) { -- printk("ip_nat_mms: partial packet %u/%u in %u/%u\n", -- exp->seq, ct_mms_info->len, -- ntohl(tcph->seq), -- ntohl(tcph->seq) + datalen); -- } -- UNLOCK_BH(&ip_mms_lock); -- return NF_DROP; -- } -- UNLOCK_BH(&ip_mms_lock); -- -- return NF_ACCEPT; --} -- --static struct ip_nat_helper mms[MAX_PORTS]; --static char mms_names[MAX_PORTS][10]; -- --/* Not __exit: called from init() */ --static void fini(void) --{ -- int i; -- -- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { -- DEBUGP("ip_nat_mms: unregistering helper for port %d\n", ports[i]); -- ip_nat_helper_unregister(&mms[i]); -- } --} -- --static int __init init(void) --{ -- int i, ret = 0; -- char *tmpname; -- -- if (ports[0] == 0) -- ports[0] = MMS_PORT; -- -- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { -- -- memset(&mms[i], 0, sizeof(struct ip_nat_helper)); -- -- mms[i].tuple.dst.protonum = IPPROTO_TCP; -- mms[i].tuple.src.u.tcp.port = htons(ports[i]); -- mms[i].mask.dst.protonum = 0xFFFF; -- mms[i].mask.src.u.tcp.port = 0xFFFF; -- mms[i].help = mms_nat_help; -- mms[i].me = THIS_MODULE; -- mms[i].flags = 0; -- mms[i].expect = mms_nat_expected; -- -- tmpname = &mms_names[i][0]; -- if (ports[i] == MMS_PORT) -- sprintf(tmpname, "mms"); -- else -- sprintf(tmpname, "mms-%d", i); -- mms[i].name = tmpname; -- -- DEBUGP("ip_nat_mms: register helper for port %d\n", -- ports[i]); -- ret = ip_nat_helper_register(&mms[i]); -- -- if (ret) { -- printk("ip_nat_mms: error registering " -- "helper for port %d\n", ports[i]); -- fini(); -- return ret; -- } -- ports_c++; -- } -- -- return ret; --} -- --module_init(init); --module_exit(fini); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_pptp.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_pptp.c ---- src/linux/linux/net/ipv4/netfilter/ip_nat_pptp.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_pptp.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,412 +0,0 @@ --/* -- * ip_nat_pptp.c - Version 1.11 -- * -- * NAT support for PPTP (Point to Point Tunneling Protocol). -- * PPTP is a a protocol for creating virtual private networks. -- * It is a specification defined by Microsoft and some vendors -- * working with Microsoft. PPTP is built on top of a modified -- * version of the Internet Generic Routing Encapsulation Protocol. -- * GRE is defined in RFC 1701 and RFC 1702. Documentation of -- * PPTP can be found in RFC 2637 -- * -- * (C) 2000-2002 by Harald Welte -- * -- * Development of this code funded by Astaro AG (http://www.astaro.com/) -- * -- * TODO: - Support for multiple calls within one session -- * (needs netfilter newnat code) -- * - NAT to a unique tuple, not to TCP source port -- * (needs netfilter tuple reservation) -- * - Support other NAT scenarios than SNAT of PNS -- * -- */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Harald Welte "); --MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP"); -- -- --#define DEBUGP(format, args...) -- --static unsigned int --pptp_nat_expected(struct sk_buff **pskb, -- unsigned int hooknum, -- struct ip_conntrack *ct, -- struct ip_nat_info *info) --{ -- struct ip_conntrack *master = master_ct(ct); -- struct ip_nat_multi_range mr; -- struct ip_ct_pptp_master *ct_pptp_info; -- struct ip_nat_pptp *nat_pptp_info; -- u_int32_t newsrcip, newdstip, newcid; -- int ret; -- -- IP_NF_ASSERT(info); -- IP_NF_ASSERT(master); -- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); -- -- DEBUGP("we have a connection!\n"); -- -- LOCK_BH(&ip_pptp_lock); -- ct_pptp_info = &master->help.ct_pptp_info; -- nat_pptp_info = &master->nat.help.nat_pptp_info; -- -- /* need to alter GRE tuple because conntrack expectfn() used 'wrong' -- * (unmanipulated) values */ -- if (hooknum == NF_IP_PRE_ROUTING) { -- DEBUGP("completing tuples with NAT info \n"); -- /* we can do this, since we're unconfirmed */ -- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key == -- htonl(ct_pptp_info->pac_call_id)) { -- /* assume PNS->PAC */ -- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = -- htonl(nat_pptp_info->pns_call_id); --// ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.gre.key = --// htonl(nat_pptp_info->pac_call_id); -- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = -- htonl(nat_pptp_info->pns_call_id); -- } else { -- /* assume PAC->PNS */ -- DEBUGP("WRONG DIRECTION\n"); -- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = -- htonl(nat_pptp_info->pac_call_id); -- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = -- htonl(nat_pptp_info->pns_call_id); -- } -- } -- -- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { -- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; -- newcid = htonl(master->nat.help.nat_pptp_info.pac_call_id); -- -- mr.rangesize = 1; -- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED; -- mr.range[0].min_ip = mr.range[0].max_ip = newdstip; -- mr.range[0].min = mr.range[0].max = -- ((union ip_conntrack_manip_proto ) { newcid }); -- DEBUGP("change dest ip to %u.%u.%u.%u\n", -- NIPQUAD(newdstip)); -- DEBUGP("change dest key to 0x%x\n", ntohl(newcid)); -- ret = ip_nat_setup_info(ct, &mr, hooknum); -- } else { -- newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -- /* nat_multi_range is in network byte order, and GRE tuple -- * is 32 bits, not 16 like callID */ -- newcid = htonl(master->help.ct_pptp_info.pns_call_id); -- -- mr.rangesize = 1; -- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS -- |IP_NAT_RANGE_PROTO_SPECIFIED; -- mr.range[0].min_ip = mr.range[0].max_ip = newsrcip; -- mr.range[0].min = mr.range[0].max = -- ((union ip_conntrack_manip_proto ) { newcid }); -- DEBUGP("change src ip to %u.%u.%u.%u\n", -- NIPQUAD(newsrcip)); -- DEBUGP("change 'src' key to 0x%x\n", ntohl(newcid)); -- ret = ip_nat_setup_info(ct, &mr, hooknum); -- } -- -- UNLOCK_BH(&ip_pptp_lock); -- -- return ret; -- --} -- --/* outbound packets == from PNS to PAC */ --static inline unsigned int --pptp_outbound_pkt(struct tcphdr *tcph, struct pptp_pkt_hdr *pptph, -- size_t datalen, -- struct ip_conntrack *ct, -- enum ip_conntrack_info ctinfo, -- struct ip_conntrack_expect *exp) -- --{ -- struct PptpControlHeader *ctlh; -- union pptp_ctrl_union pptpReq; -- struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info; -- struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info; -- -- u_int16_t msg, *cid = NULL, new_callid; -- -- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph)); -- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh)); -- -- new_callid = htons(ct_pptp_info->pns_call_id); -- -- switch (msg = ntohs(ctlh->messageType)) { -- case PPTP_OUT_CALL_REQUEST: -- cid = &pptpReq.ocreq->callID; -- -- /* save original call ID in nat_info */ -- nat_pptp_info->pns_call_id = ct_pptp_info->pns_call_id; -- -- new_callid = tcph->source; -- /* save new call ID in ct info */ -- ct_pptp_info->pns_call_id = ntohs(new_callid); -- break; -- case PPTP_IN_CALL_REPLY: -- cid = &pptpReq.icreq->callID; -- break; -- case PPTP_CALL_CLEAR_REQUEST: -- cid = &pptpReq.clrreq->callID; -- break; -- case PPTP_CALL_DISCONNECT_NOTIFY: -- cid = &pptpReq.disc->callID; -- break; -- -- default: -- DEBUGP("unknown outbound packet 0x%04x:%s\n", msg, -- (msg <= PPTP_MSG_MAX)? strMName[msg]:strMName[0]); -- /* fall through */ -- -- case PPTP_SET_LINK_INFO: -- /* only need to NAT in case PAC is behind NAT box */ -- case PPTP_START_SESSION_REQUEST: -- case PPTP_START_SESSION_REPLY: -- case PPTP_STOP_SESSION_REQUEST: -- case PPTP_STOP_SESSION_REPLY: -- case PPTP_ECHO_REQUEST: -- case PPTP_ECHO_REPLY: -- /* no need to alter packet */ -- return NF_ACCEPT; -- } -- -- IP_NF_ASSERT(cid); -- -- DEBUGP("altering call id from 0x%04x to 0x%04x\n", -- ntohs(*cid), ntohs(new_callid)); -- /* mangle packet */ -- tcph->check = ip_nat_cheat_check(*cid^0xFFFF, -- new_callid, tcph->check); -- *cid = new_callid; -- -- return NF_ACCEPT; --} -- --/* inbound packets == from PAC to PNS */ --static inline unsigned int --pptp_inbound_pkt(struct tcphdr *tcph, struct pptp_pkt_hdr *pptph, -- size_t datalen, -- struct ip_conntrack *ct, -- enum ip_conntrack_info ctinfo, -- struct ip_conntrack_expect *oldexp) --{ -- struct PptpControlHeader *ctlh; -- union pptp_ctrl_union pptpReq; -- struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info; -- struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info; -- -- u_int16_t msg, new_cid = 0, new_pcid, *pcid = NULL, *cid = NULL; -- u_int32_t old_dst_ip; -- -- struct ip_conntrack_tuple t; -- -- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph)); -- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh)); -- -- new_pcid = htons(nat_pptp_info->pns_call_id); -- -- switch (msg = ntohs(ctlh->messageType)) { -- case PPTP_OUT_CALL_REPLY: -- pcid = &pptpReq.ocack->peersCallID; -- cid = &pptpReq.ocack->callID; -- if (!oldexp) { -- DEBUGP("outcall but no expectation\n"); -- break; -- } -- old_dst_ip = oldexp->tuple.dst.ip; -- t = oldexp->tuple; -- -- /* save original PAC call ID in nat_info */ -- nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id; -- -- /* store new callID in ct_info, so conntrack works */ -- //ct_pptp_info->pac_call_id = ntohs(tcph->source); -- //new_cid = htons(ct_pptp_info->pac_call_id); -- -- /* alter expectation */ -- if (t.dst.ip == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip) { -- /* expectation for PNS->PAC direction */ -- t.dst.u.gre.key = htonl(ct_pptp_info->pac_call_id); -- t.src.u.gre.key = htonl(nat_pptp_info->pns_call_id); -- } else { -- /* expectation for PAC->PNS direction */ -- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -- DEBUGP("EXPECTATION IN WRONG DIRECTION!!!\n"); -- } -- -- if (!ip_conntrack_change_expect(oldexp, &t)) { -- DEBUGP("successfully changed expect\n"); -- } else { -- DEBUGP("can't change expect\n"); -- } -- ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_orig, &t); -- /* reply keymap */ -- t.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; -- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -- t.src.u.gre.key = htonl(nat_pptp_info->pac_call_id); -- t.dst.u.gre.key = htonl(ct_pptp_info->pns_call_id); -- ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_reply, &t); -- -- break; -- case PPTP_IN_CALL_CONNECT: -- pcid = &pptpReq.iccon->peersCallID; -- if (!oldexp) -- break; -- old_dst_ip = oldexp->tuple.dst.ip; -- t = oldexp->tuple; -- -- /* alter expectation, no need for callID */ -- if (t.dst.ip == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip) { -- /* expectation for PNS->PAC direction */ -- t.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -- } else { -- /* expectation for PAC->PNS direction */ -- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; -- } -- -- if (!ip_conntrack_change_expect(oldexp, &t)) { -- DEBUGP("successfully changed expect\n"); -- } else { -- DEBUGP("can't change expect\n"); -- } -- break; -- case PPTP_IN_CALL_REQUEST: -- /* only need to nat in case PAC is behind NAT box */ -- break; -- case PPTP_WAN_ERROR_NOTIFY: -- pcid = &pptpReq.wanerr->peersCallID; -- break; -- default: -- DEBUGP("unknown inbound packet %s\n", -- (msg <= PPTP_MSG_MAX)? strMName[msg]:strMName[0]); -- /* fall through */ -- -- case PPTP_START_SESSION_REQUEST: -- case PPTP_START_SESSION_REPLY: -- case PPTP_STOP_SESSION_REQUEST: -- case PPTP_ECHO_REQUEST: -- case PPTP_ECHO_REPLY: -- /* no need to alter packet */ -- return NF_ACCEPT; -- } -- -- /* mangle packet */ -- IP_NF_ASSERT(pcid); -- DEBUGP("altering peer call id from 0x%04x to 0x%04x\n", -- ntohs(*pcid), ntohs(new_pcid)); -- tcph->check = ip_nat_cheat_check(*pcid^0xFFFF, -- new_pcid, tcph->check); -- *pcid = new_pcid; -- -- if (new_cid) { -- IP_NF_ASSERT(cid); -- DEBUGP("altering call id from 0x%04x to 0x%04x\n", -- ntohs(*cid), ntohs(new_cid)); -- tcph->check = ip_nat_cheat_check(*cid^0xFFFF, -- new_cid, tcph->check); -- *cid = new_cid; -- } -- -- /* great, at least we don't need to resize packets */ -- return NF_ACCEPT; --} -- -- --static unsigned int tcp_help(struct ip_conntrack *ct, -- struct ip_conntrack_expect *exp, -- struct ip_nat_info *info, -- enum ip_conntrack_info ctinfo, -- unsigned int hooknum, struct sk_buff **pskb) --{ -- struct iphdr *iph = (*pskb)->nh.iph; -- struct tcphdr *tcph = (void *) iph + iph->ihl*4; -- unsigned int datalen = (*pskb)->len - iph->ihl*4 - tcph->doff*4; -- struct pptp_pkt_hdr *pptph; -- void *datalimit; -- -- int dir; -- -- DEBUGP("entering\n"); -- -- /* Only mangle things once: original direction in POST_ROUTING -- and reply direction on PRE_ROUTING. */ -- dir = CTINFO2DIR(ctinfo); -- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) -- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { -- DEBUGP("Not touching dir %s at hook %s\n", -- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", -- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" -- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" -- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); -- return NF_ACCEPT; -- } -- -- /* if packet is too small, just skip it */ -- if (datalen < sizeof(struct pptp_pkt_hdr)+ -- sizeof(struct PptpControlHeader)) { -- DEBUGP("pptp packet too short\n"); -- return NF_ACCEPT; -- } -- -- -- pptph = (struct pptp_pkt_hdr *) ((void *)tcph + tcph->doff*4); -- datalimit = (void *) pptph + datalen; -- -- LOCK_BH(&ip_pptp_lock); -- -- if (dir == IP_CT_DIR_ORIGINAL) { -- /* reuqests sent by client to server (PNS->PAC) */ -- pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo, exp); -- } else { -- /* response from the server to the client (PAC->PNS) */ -- pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo, exp); -- } -- -- UNLOCK_BH(&ip_pptp_lock); -- -- return NF_ACCEPT; --} -- --/* nat helper struct for control connection */ --static struct ip_nat_helper pptp_tcp_helper = { -- { NULL, NULL }, -- "pptp", IP_NAT_HELPER_F_ALWAYS, THIS_MODULE, -- { { 0, { tcp: { port: __constant_htons(PPTP_CONTROL_PORT) } } }, -- { 0, { 0 }, IPPROTO_TCP } }, -- { { 0, { tcp: { port: 0xFFFF } } }, -- { 0, { 0 }, 0xFFFF } }, -- tcp_help, pptp_nat_expected }; -- -- --static int __init init(void) --{ -- DEBUGP("init_module\n" ); -- -- if (ip_nat_helper_register(&pptp_tcp_helper)) -- return -EIO; -- -- return 0; --} -- --static void __exit fini(void) --{ -- DEBUGP("cleanup_module\n" ); -- ip_nat_helper_unregister(&pptp_tcp_helper); --} -- --module_init(init); --module_exit(fini); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_proto_gre.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_proto_gre.c ---- src/linux/linux/net/ipv4/netfilter/ip_nat_proto_gre.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_proto_gre.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,212 +0,0 @@ --/* -- * ip_nat_proto_gre.c - Version 1.11 -- * -- * NAT protocol helper module for GRE. -- * -- * GRE is a generic encapsulation protocol, which is generally not very -- * suited for NAT, as it has no protocol-specific part as port numbers. -- * -- * It has an optional key field, which may help us distinguishing two -- * connections between the same two hosts. -- * -- * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 -- * -- * PPTP is built on top of a modified version of GRE, and has a mandatory -- * field called "CallID", which serves us for the same purpose as the key -- * field in plain GRE. -- * -- * Documentation about PPTP can be found in RFC 2637 -- * -- * (C) 2000-2002 by Harald Welte -- * -- * Development of this code funded by Astaro AG (http://www.astaro.com/) -- * -- */ -- --#include --#include --#include --#include --#include --#include --#include -- --MODULE_LICENSE("GPL"); --MODULE_AUTHOR("Harald Welte "); --MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); -- --#define DEBUGP(x, args...) -- --/* is key in given range between min and max */ --static int --gre_in_range(const struct ip_conntrack_tuple *tuple, -- enum ip_nat_manip_type maniptype, -- const union ip_conntrack_manip_proto *min, -- const union ip_conntrack_manip_proto *max) --{ -- return ntohl(tuple->src.u.gre.key) >= ntohl(min->gre.key) -- && ntohl(tuple->src.u.gre.key) <= ntohl(max->gre.key); --} -- --/* generate unique tuple ... */ --static int --gre_unique_tuple(struct ip_conntrack_tuple *tuple, -- const struct ip_nat_range *range, -- enum ip_nat_manip_type maniptype, -- const struct ip_conntrack *conntrack) --{ -- u_int32_t min, i, range_size; -- u_int32_t key = 0, *keyptr; -- -- if (maniptype == IP_NAT_MANIP_SRC) -- keyptr = &tuple->src.u.gre.key; -- else -- keyptr = &tuple->dst.u.gre.key; -- -- if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { -- -- switch (tuple->dst.u.gre.version) { -- case 0: -- DEBUGP("NATing GRE version 0 (ct=%p)\n", -- conntrack); -- min = 1; -- range_size = 0xffffffff; -- break; -- case GRE_VERSION_PPTP: -- DEBUGP("%p: NATing GRE PPTP\n", -- conntrack); -- min = 1; -- range_size = 0xffff; -- break; -- default: -- printk(KERN_WARNING "nat_gre: unknown GRE version\n"); -- return 0; -- break; -- } -- -- } else { -- min = ntohl(range->min.gre.key); -- range_size = ntohl(range->max.gre.key) - min + 1; -- } -- -- DEBUGP("min = %u, range_size = %u\n", min, range_size); -- -- for (i = 0; i < range_size; i++, key++) { -- *keyptr = htonl(min + key % range_size); -- if (!ip_nat_used_tuple(tuple, conntrack)) -- return 1; -- } -- -- DEBUGP("%p: no NAT mapping\n", conntrack); -- -- return 0; --} -- --/* manipulate a GRE packet according to maniptype */ --static void --gre_manip_pkt(struct iphdr *iph, size_t len, -- const struct ip_conntrack_manip *manip, -- enum ip_nat_manip_type maniptype) --{ -- struct gre_hdr *greh = (struct gre_hdr *)((u_int32_t *)iph+iph->ihl); -- struct gre_hdr_pptp *pgreh = (struct gre_hdr_pptp *) greh; -- -- /* we only have destination manip of a packet, since 'source key' -- * is not present in the packet itself */ -- if (maniptype == IP_NAT_MANIP_DST) { -- /* key manipulation is always dest */ -- switch (greh->version) { -- case 0: -- if (!greh->key) { -- DEBUGP("can't nat GRE w/o key\n"); -- break; -- } -- if (greh->csum) { -- *(gre_csum(greh)) = -- ip_nat_cheat_check(~*(gre_key(greh)), -- manip->u.gre.key, -- *(gre_csum(greh))); -- } -- *(gre_key(greh)) = manip->u.gre.key; -- break; -- case GRE_VERSION_PPTP: -- DEBUGP("call_id -> 0x%04x\n", -- ntohl(manip->u.gre.key)); -- pgreh->call_id = htons(ntohl(manip->u.gre.key)); -- break; -- default: -- DEBUGP("can't nat unknown GRE version\n"); -- break; -- } -- } --} -- --/* print out a nat tuple */ --static unsigned int --gre_print(char *buffer, -- const struct ip_conntrack_tuple *match, -- const struct ip_conntrack_tuple *mask) --{ -- unsigned int len = 0; -- -- if (mask->dst.u.gre.version) -- len += sprintf(buffer + len, "version=%d ", -- ntohs(match->dst.u.gre.version)); -- -- if (mask->dst.u.gre.protocol) -- len += sprintf(buffer + len, "protocol=0x%x ", -- ntohs(match->dst.u.gre.protocol)); -- -- if (mask->src.u.gre.key) -- len += sprintf(buffer + len, "srckey=0x%x ", -- ntohl(match->src.u.gre.key)); -- -- if (mask->dst.u.gre.key) -- len += sprintf(buffer + len, "dstkey=0x%x ", -- ntohl(match->src.u.gre.key)); -- -- return len; --} -- --/* print a range of keys */ --static unsigned int --gre_print_range(char *buffer, const struct ip_nat_range *range) --{ -- if (range->min.gre.key != 0 -- || range->max.gre.key != 0xFFFF) { -- if (range->min.gre.key == range->max.gre.key) -- return sprintf(buffer, "key 0x%x ", -- ntohl(range->min.gre.key)); -- else -- return sprintf(buffer, "keys 0x%u-0x%u ", -- ntohl(range->min.gre.key), -- ntohl(range->max.gre.key)); -- } else -- return 0; --} -- --/* nat helper struct */ --static struct ip_nat_protocol gre = -- { { NULL, NULL }, "GRE", IPPROTO_GRE, -- gre_manip_pkt, -- gre_in_range, -- gre_unique_tuple, -- gre_print, -- gre_print_range -- }; -- --static int __init init(void) --{ -- if (ip_nat_protocol_register(&gre)) -- return -EIO; -- -- return 0; --} -- --static void __exit fini(void) --{ -- ip_nat_protocol_unregister(&gre); --} -- --module_init(init); --module_exit(fini); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_standalone.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_standalone.c ---- src/linux/linux/net/ipv4/netfilter/ip_nat_standalone.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_standalone.c 2004-05-09 04:13:03.000000000 -0400 -@@ -37,7 +37,11 @@ - #include - #include - -+#if 0 -+#define DEBUGP printk -+#else - #define DEBUGP(format, args...) -+#endif - - #define HOOKNAME(hooknum) ((hooknum) == NF_IP_POST_ROUTING ? "POST_ROUTING" \ - : ((hooknum) == NF_IP_PRE_ROUTING ? "PRE_ROUTING" \ -@@ -354,6 +358,5 @@ - EXPORT_SYMBOL(ip_nat_helper_unregister); - EXPORT_SYMBOL(ip_nat_cheat_check); - EXPORT_SYMBOL(ip_nat_mangle_tcp_packet); --EXPORT_SYMBOL(ip_nat_mangle_udp_packet); - EXPORT_SYMBOL(ip_nat_used_tuple); - MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_tftp.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_tftp.c ---- src/linux/linux/net/ipv4/netfilter/ip_nat_tftp.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_tftp.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,186 +0,0 @@ --/* -- * Licensed under GNU GPL version 2 Copyright Magnus Boden -- * Version: 0.0.7 -- * -- * Thu 21 Mar 2002 Harald Welte -- * - Port to newnat API -- * -- * This module currently supports DNAT: -- * iptables -t nat -A PREROUTING -d x.x.x.x -j DNAT --to-dest x.x.x.y -- * -- * and SNAT: -- * iptables -t nat -A POSTROUTING { -j MASQUERADE , -j SNAT --to-source x.x.x.x } -- * -- * It has not been tested with -- * -j SNAT --to-source x.x.x.x-x.x.x.y since I only have one external ip -- * If you do test this please let me know if it works or not. -- * -- */ -- --#include --#include --#include --#include -- --#include --#include --#include --#include --#include --#include -- --MODULE_AUTHOR("Magnus Boden "); --MODULE_DESCRIPTION("Netfilter NAT helper for tftp"); --MODULE_LICENSE("GPL"); -- --#define MAX_PORTS 8 -- --static int ports[MAX_PORTS]; --static int ports_c = 0; --#ifdef MODULE_PARM --MODULE_PARM(ports,"1-" __MODULE_STRING(MAX_PORTS) "i"); --MODULE_PARM_DESC(ports, "port numbers of tftp servers"); --#endif -- --#define DEBUGP(format, args...) --static unsigned int --tftp_nat_help(struct ip_conntrack *ct, -- struct ip_conntrack_expect *exp, -- struct ip_nat_info *info, -- enum ip_conntrack_info ctinfo, -- unsigned int hooknum, -- struct sk_buff **pskb) --{ -- int dir = CTINFO2DIR(ctinfo); -- struct iphdr *iph = (*pskb)->nh.iph; -- struct udphdr *udph = (void *)iph + iph->ihl * 4; -- struct tftphdr *tftph = (void *)udph + 8; -- struct ip_conntrack_tuple repl; -- -- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) -- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) -- return NF_ACCEPT; -- -- if (!exp) { -- DEBUGP("no conntrack expectation to modify\n"); -- return NF_ACCEPT; -- } -- -- switch (ntohs(tftph->opcode)) { -- /* RRQ and WRQ works the same way */ -- case TFTP_OPCODE_READ: -- case TFTP_OPCODE_WRITE: -- repl = ct->tuplehash[IP_CT_DIR_REPLY].tuple; -- DEBUGP(""); -- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); -- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); -- DEBUGP("expecting: "); -- DUMP_TUPLE_RAW(&repl); -- DUMP_TUPLE_RAW(&exp->mask); -- ip_conntrack_change_expect(exp, &repl); -- break; -- default: -- DEBUGP("Unknown opcode\n"); -- } -- -- return NF_ACCEPT; --} -- --static unsigned int --tftp_nat_expected(struct sk_buff **pskb, -- unsigned int hooknum, -- struct ip_conntrack *ct, -- struct ip_nat_info *info) --{ -- const struct ip_conntrack *master = ct->master->expectant; -- const struct ip_conntrack_tuple *orig = -- &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple; -- struct ip_nat_multi_range mr; -- -- IP_NF_ASSERT(info); -- IP_NF_ASSERT(master); -- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); -- -- mr.rangesize = 1; -- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; -- -- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) { -- mr.range[0].min_ip = mr.range[0].max_ip = orig->dst.ip; -- DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u " -- "newsrc: %u.%u.%u.%u\n", -- NIPQUAD((*pskb)->nh.iph->saddr), ntohs(udph->source), -- NIPQUAD((*pskb)->nh.iph->daddr), ntohs(udph->dest), -- NIPQUAD(orig->dst.ip)); -- } else { -- mr.range[0].min_ip = mr.range[0].max_ip = orig->src.ip; -- mr.range[0].min.udp.port = mr.range[0].max.udp.port = -- orig->src.u.udp.port; -- mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; -- -- DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u " -- "newdst: %u.%u.%u.%u:%u\n", -- NIPQUAD((*pskb)->nh.iph->saddr), ntohs(udph->source), -- NIPQUAD((*pskb)->nh.iph->daddr), ntohs(udph->dest), -- NIPQUAD(orig->src.ip), ntohs(orig->src.u.udp.port)); -- } -- -- return ip_nat_setup_info(ct,&mr,hooknum); --} -- --static struct ip_nat_helper tftp[MAX_PORTS]; --static char tftp_names[MAX_PORTS][10]; -- --static void fini(void) --{ -- int i; -- -- for (i = 0 ; i < ports_c; i++) { -- DEBUGP("unregistering helper for port %d\n", ports[i]); -- ip_nat_helper_unregister(&tftp[i]); -- } --} -- --static int __init init(void) --{ -- int i, ret; -- char *tmpname; -- -- if (!ports[0]) -- ports[0] = TFTP_PORT; -- -- for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { -- memset(&tftp[i], 0, sizeof(struct ip_nat_helper)); -- -- tftp[i].tuple.dst.protonum = IPPROTO_UDP; -- tftp[i].tuple.src.u.udp.port = htons(ports[i]); -- tftp[i].mask.dst.protonum = 0xFFFF; -- tftp[i].mask.src.u.udp.port = 0xFFFF; -- tftp[i].help = tftp_nat_help; -- tftp[i].flags = 0; -- tftp[i].me = THIS_MODULE; -- tftp[i].expect = tftp_nat_expected; -- -- tmpname = &tftp_names[i][0]; -- if (ports[i] == TFTP_PORT) -- sprintf(tmpname, "tftp"); -- else -- sprintf(tmpname, "tftp-%d", i); -- tftp[i].name = tmpname; -- -- DEBUGP("ip_nat_tftp: registering for port %d: name %s\n", -- ports[i], tftp[i].name); -- ret = ip_nat_helper_register(&tftp[i]); -- -- if (ret) { -- printk("ip_nat_tftp: unable to register for port %d\n", -- ports[i]); -- fini(); -- return ret; -- } -- ports_c++; -- } -- return ret; --} -- --module_init(init); --module_exit(fini); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_pool.c src/linux/linux.stock/net/ipv4/netfilter/ip_pool.c ---- src/linux/linux/net/ipv4/netfilter/ip_pool.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ip_pool.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,328 +0,0 @@ --/* Kernel module for IP pool management */ -- --#include --#include --#include --#include --#include --#include --#include --#include --#include --#include -- --#define DP(format, args...) -- --MODULE_LICENSE("GPL"); -- --#define NR_POOL 16 --static int nr_pool = NR_POOL;/* overwrite this when loading module */ -- --struct ip_pool { -- u_int32_t first_ip; /* host byte order, included in range */ -- u_int32_t last_ip; /* host byte order, included in range */ -- void *members; /* the bitmap proper */ -- int nr_use; /* total nr. of tests through this */ -- int nr_match; /* total nr. of matches through this */ -- rwlock_t lock; --}; -- --static struct ip_pool *POOL; -- --static inline struct ip_pool *lookup(ip_pool_t index) --{ -- if (index < 0 || index >= nr_pool) { -- DP("ip_pool:lookup: bad index %d\n", index); -- return 0; -- } -- return POOL+index; --} -- --int ip_pool_match(ip_pool_t index, u_int32_t addr) --{ -- struct ip_pool *pool = lookup(index); -- int res = 0; -- -- if (!pool || !pool->members) -- return 0; -- read_lock_bh(&pool->lock); -- if (pool->members) { -- if (addr >= pool->first_ip && addr <= pool->last_ip) { -- addr -= pool->first_ip; -- if (test_bit(addr, pool->members)) { -- res = 1; --#ifdef CONFIG_IP_POOL_STATISTICS -- pool->nr_match++; --#endif -- } -- } --#ifdef CONFIG_IP_POOL_STATISTICS -- pool->nr_use++; --#endif -- } -- read_unlock_bh(&pool->lock); -- return res; --} -- --static int pool_change(ip_pool_t index, u_int32_t addr, int isdel) --{ -- struct ip_pool *pool; -- int res = -1; -- -- pool = lookup(index); -- if ( !pool || !pool->members -- || addr < pool->first_ip || addr > pool->last_ip) -- return -1; -- read_lock_bh(&pool->lock); -- if (pool->members && addr >= pool->first_ip && addr <= pool->last_ip) { -- addr -= pool->first_ip; -- res = isdel -- ? (0 != test_and_clear_bit(addr, pool->members)) -- : (0 != test_and_set_bit(addr, pool->members)); -- } -- read_unlock_bh(&pool->lock); -- return res; --} -- --int ip_pool_mod(ip_pool_t index, u_int32_t addr, int isdel) --{ -- int res = pool_change(index,addr,isdel); -- -- if (!isdel) res = !res; -- return res; --} -- --static inline int bitmap_bytes(u_int32_t a, u_int32_t b) --{ -- return 4*((((b-a+8)/8)+3)/4); --} -- --static inline int poolbytes(ip_pool_t index) --{ -- struct ip_pool *pool = lookup(index); -- -- return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0; --} -- --static int setpool( -- struct sock *sk, -- int optval, -- void *user, -- unsigned int len --) { -- struct ip_pool_request req; -- -- DP("ip_pool:setpool: optval=%d, user=%p, len=%d\n", optval, user, len); -- if (!capable(CAP_NET_ADMIN)) -- return -EPERM; -- if (optval != SO_IP_POOL) -- return -EBADF; -- if (len != sizeof(req)) -- return -EINVAL; -- if (copy_from_user(&req, user, sizeof(req)) != 0) -- return -EFAULT; -- printk("obsolete op - upgrade your ippool(8) utility.\n"); -- return -EINVAL; --} -- --static int getpool( -- struct sock *sk, -- int optval, -- void *user, -- int *len --) { -- struct ip_pool_request req; -- struct ip_pool *pool; -- ip_pool_t i; -- int newbytes; -- void *newmembers; -- int res; -- -- DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user); -- if (!capable(CAP_NET_ADMIN)) -- return -EINVAL; -- if (optval != SO_IP_POOL) -- return -EINVAL; -- if (*len != sizeof(req)) { -- return -EFAULT; -- } -- if (copy_from_user(&req, user, sizeof(req)) != 0) -- return -EFAULT; -- DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index); -- if (req.op < IP_POOL_BAD001) { -- printk("obsolete op - upgrade your ippool(8) utility.\n"); -- return -EFAULT; -- } -- switch(req.op) { -- case IP_POOL_HIGH_NR: -- DP("ip_pool HIGH_NR\n"); -- req.index = IP_POOL_NONE; -- for (i=0; imembers) -- return -EBADF; -- req.addr = htonl(pool->first_ip); -- req.addr2 = htonl(pool->last_ip); -- return copy_to_user(user, &req, sizeof(req)); -- case IP_POOL_USAGE: -- DP("ip_pool USE\n"); -- pool = lookup(req.index); -- if (!pool) -- return -EINVAL; -- if (!pool->members) -- return -EBADF; -- req.addr = pool->nr_use; -- req.addr2 = pool->nr_match; -- return copy_to_user(user, &req, sizeof(req)); -- case IP_POOL_TEST_ADDR: -- DP("ip_pool TEST 0x%08x\n", req.addr); -- pool = lookup(req.index); -- if (!pool) -- return -EINVAL; -- res = 0; -- read_lock_bh(&pool->lock); -- if (!pool->members) { -- DP("ip_pool TEST_ADDR no members in pool\n"); -- res = -EBADF; -- goto unlock_and_return_res; -- } -- req.addr = ntohl(req.addr); -- if (req.addr < pool->first_ip) { -- DP("ip_pool TEST_ADDR address < pool bounds\n"); -- res = -ERANGE; -- goto unlock_and_return_res; -- } -- if (req.addr > pool->last_ip) { -- DP("ip_pool TEST_ADDR address > pool bounds\n"); -- res = -ERANGE; -- goto unlock_and_return_res; -- } -- req.addr = (0 != test_bit((req.addr - pool->first_ip), -- pool->members)); -- read_unlock_bh(&pool->lock); -- return copy_to_user(user, &req, sizeof(req)); -- case IP_POOL_FLUSH: -- DP("ip_pool FLUSH not yet implemented.\n"); -- return -EBUSY; -- case IP_POOL_DESTROY: -- DP("ip_pool DESTROY not yet implemented.\n"); -- return -EBUSY; -- case IP_POOL_INIT: -- DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2); -- pool = lookup(req.index); -- if (!pool) -- return -EINVAL; -- req.addr = ntohl(req.addr); -- req.addr2 = ntohl(req.addr2); -- if (req.addr > req.addr2) { -- DP("ip_pool INIT bad ip range\n"); -- return -EINVAL; -- } -- newbytes = bitmap_bytes(req.addr, req.addr2); -- newmembers = kmalloc(newbytes, GFP_KERNEL); -- if (!newmembers) { -- DP("ip_pool INIT out of mem for %d bytes\n", newbytes); -- return -ENOMEM; -- } -- memset(newmembers, 0, newbytes); -- write_lock_bh(&pool->lock); -- if (pool->members) { -- DP("ip_pool INIT pool %d exists\n", req.index); -- kfree(newmembers); -- res = -EBUSY; -- goto unlock_and_return_res; -- } -- pool->first_ip = req.addr; -- pool->last_ip = req.addr2; -- pool->nr_use = 0; -- pool->nr_match = 0; -- pool->members = newmembers; -- write_unlock_bh(&pool->lock); -- return 0; -- case IP_POOL_ADD_ADDR: -- DP("ip_pool ADD_ADDR 0x%08x\n", req.addr); -- req.addr = pool_change(req.index, ntohl(req.addr), 0); -- return copy_to_user(user, &req, sizeof(req)); -- case IP_POOL_DEL_ADDR: -- DP("ip_pool DEL_ADDR 0x%08x\n", req.addr); -- req.addr = pool_change(req.index, ntohl(req.addr), 1); -- return copy_to_user(user, &req, sizeof(req)); -- default: -- DP("ip_pool:getpool bad op %d\n", req.op); -- return -EINVAL; -- } -- return -EINVAL; -- --unlock_and_return_res: -- if (pool) -- read_unlock_bh(&pool->lock); -- return res; --} -- --static struct nf_sockopt_ops so_pool --= { { NULL, NULL }, PF_INET, -- SO_IP_POOL, SO_IP_POOL+1, &setpool, -- SO_IP_POOL, SO_IP_POOL+1, &getpool, -- 0, NULL }; -- --MODULE_PARM(nr_pool, "i"); -- --static int __init init(void) --{ -- ip_pool_t i; -- int res; -- -- if (nr_pool < 1) { -- printk("ip_pool module init: bad nr_pool %d\n", nr_pool); -- return -EINVAL; -- } -- POOL = kmalloc(nr_pool * sizeof(*POOL), GFP_KERNEL); -- if (!POOL) { -- printk("ip_pool module init: out of memory for nr_pool %d\n", -- nr_pool); -- return -ENOMEM; -- } -- for (i=0; i - #include - -+#if 0 -+/* All the better to debug you with... */ -+#define static -+#define inline -+#endif - - /* Locking is simple: we assume at worst case there will be one packet - in user context and one from bottom halves (or soft irq if Alexey's -@@ -83,6 +88,7 @@ - { - /* Size per table */ - unsigned int size; -+ /* Number of entries: FIXME. --RR */ - unsigned int number; - /* Initial number of entries. Needed for module usage count */ - unsigned int initial_entries; -@@ -106,6 +112,11 @@ - #define TABLE_OFFSET(t,p) 0 - #endif - -+#if 0 -+#define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) -+#define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) -+#define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0) -+#endif - - /* Returns whether matches rule or not. */ - static inline int -@@ -408,6 +419,12 @@ - { - void *ret; - -+#if 0 -+ duprintf("find_inlist: searching for `%s' in %s.\n", -+ name, head == &ipt_target ? "ipt_target" -+ : head == &ipt_match ? "ipt_match" -+ : head == &ipt_tables ? "ipt_tables" : "UNKNOWN"); -+#endif - - *error = down_interruptible(mutex); - if (*error != 0) -@@ -745,6 +762,8 @@ - newinfo->underflow[h] = underflows[h]; - } - -+ /* FIXME: underflows must be unconditional, standard verdicts -+ < 0 (not IPT_RETURN). --RR */ - - /* Clear counters and comefrom */ - e->counters = ((struct ipt_counters) { 0, 0 }); -@@ -957,6 +976,7 @@ - goto free_counters; - } - -+ /* FIXME: use iterator macros --RR */ - /* ... then go back and fix counters and names */ - for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ - unsigned int i; -@@ -1134,6 +1154,14 @@ - const struct ipt_counters addme[], - unsigned int *i) - { -+#if 0 -+ duprintf("add_counter: Entry %u %lu/%lu + %lu/%lu\n", -+ *i, -+ (long unsigned int)e->counters.pcnt, -+ (long unsigned int)e->counters.bcnt, -+ (long unsigned int)addme[*i].pcnt, -+ (long unsigned int)addme[*i].bcnt); -+#endif - - ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt); - -@@ -1495,6 +1523,7 @@ - return 0; - } - -+ /* FIXME: Try tcp doff >> packet len against various stacks --RR */ - - #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) - -@@ -1670,15 +1699,14 @@ - = { { NULL, NULL }, "icmp", &icmp_match, &icmp_checkentry, NULL }; - - #ifdef CONFIG_PROC_FS --static inline int print_name(const char *i, -+static inline int print_name(const struct ipt_table *t, - off_t start_offset, char *buffer, int length, - off_t *pos, unsigned int *count) - { - if ((*count)++ >= start_offset) { - unsigned int namelen; - -- namelen = sprintf(buffer + *pos, "%s\n", -- i + sizeof(struct list_head)); -+ namelen = sprintf(buffer + *pos, "%s\n", t->name); - if (*pos + namelen > length) { - /* Stop iterating */ - return 1; -@@ -1696,7 +1724,7 @@ - if (down_interruptible(&ipt_mutex) != 0) - return 0; - -- LIST_FIND(&ipt_tables, print_name, void *, -+ LIST_FIND(&ipt_tables, print_name, struct ipt_table *, - offset, buffer, length, &pos, &count); - - up(&ipt_mutex); -@@ -1705,46 +1733,6 @@ - *start=(char *)((unsigned long)count-offset); - return pos; - } -- --static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) --{ -- off_t pos = 0; -- unsigned int count = 0; -- -- if (down_interruptible(&ipt_mutex) != 0) -- return 0; -- -- LIST_FIND(&ipt_target, print_name, void *, -- offset, buffer, length, &pos, &count); -- -- up(&ipt_mutex); -- -- *start = (char *)((unsigned long)count - offset); -- return pos; --} -- --static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) --{ -- off_t pos = 0; -- unsigned int count = 0; -- -- if (down_interruptible(&ipt_mutex) != 0) -- return 0; -- -- LIST_FIND(&ipt_match, print_name, void *, -- offset, buffer, length, &pos, &count); -- -- up(&ipt_mutex); -- -- *start = (char *)((unsigned long)count - offset); -- return pos; --} -- --static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = --{ { "ip_tables_names", ipt_get_tables }, -- { "ip_tables_targets", ipt_get_targets }, -- { "ip_tables_matches", ipt_get_matches }, -- { NULL, NULL} }; - #endif /*CONFIG_PROC_FS*/ - - static int __init init(void) -@@ -1770,20 +1758,14 @@ - #ifdef CONFIG_PROC_FS - { - struct proc_dir_entry *proc; -- int i; - -- for (i = 0; ipt_proc_entry[i].name; i++) { -- proc = proc_net_create(ipt_proc_entry[i].name, 0, -- ipt_proc_entry[i].get_info); -+ proc = proc_net_create("ip_tables_names", 0, ipt_get_tables); - if (!proc) { -- while (--i >= 0) -- proc_net_remove(ipt_proc_entry[i].name); - nf_unregister_sockopt(&ipt_sockopts); - return -ENOMEM; - } - proc->owner = THIS_MODULE; - } -- } - #endif - - printk("ip_tables: (C) 2000-2002 Netfilter core team\n"); -@@ -1794,11 +1776,7 @@ - { - nf_unregister_sockopt(&ipt_sockopts); - #ifdef CONFIG_PROC_FS -- { -- int i; -- for (i = 0; ipt_proc_entry[i].name; i++) -- proc_net_remove(ipt_proc_entry[i].name); -- } -+ proc_net_remove("ip_tables_names"); - #endif - } - -diff -Nurb src/linux/linux/net/ipv4/netfilter/ipchains_core.c src/linux/linux.stock/net/ipv4/netfilter/ipchains_core.c ---- src/linux/linux/net/ipv4/netfilter/ipchains_core.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ipchains_core.c 2004-05-09 04:13:03.000000000 -0400 -@@ -977,10 +977,17 @@ - || ftmp->ipfw.fw_dst.s_addr!=frwl->ipfw.fw_dst.s_addr - || ftmp->ipfw.fw_smsk.s_addr!=frwl->ipfw.fw_smsk.s_addr - || ftmp->ipfw.fw_dmsk.s_addr!=frwl->ipfw.fw_dmsk.s_addr -+#if 0 -+ || ftmp->ipfw.fw_flg!=frwl->ipfw.fw_flg -+#else - || ((ftmp->ipfw.fw_flg & ~IP_FW_F_MARKABS) - != (frwl->ipfw.fw_flg & ~IP_FW_F_MARKABS)) -+#endif - || ftmp->ipfw.fw_invflg!=frwl->ipfw.fw_invflg - || ftmp->ipfw.fw_proto!=frwl->ipfw.fw_proto -+#if 0 -+ || ftmp->ipfw.fw_mark!=frwl->ipfw.fw_mark -+#endif - || ftmp->ipfw.fw_redirpt!=frwl->ipfw.fw_redirpt - || ftmp->ipfw.fw_spts[0]!=frwl->ipfw.fw_spts[0] - || ftmp->ipfw.fw_spts[1]!=frwl->ipfw.fw_spts[1] -@@ -1566,6 +1573,7 @@ - ) - { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) -+ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ - int reset = 0; - #endif - struct ip_chain *i; -diff -Nurb src/linux/linux/net/ipv4/netfilter/ipfwadm_core.c src/linux/linux.stock/net/ipv4/netfilter/ipfwadm_core.c ---- src/linux/linux/net/ipv4/netfilter/ipfwadm_core.c 2003-10-14 04:09:33.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ipfwadm_core.c 2004-05-09 04:13:03.000000000 -0400 -@@ -20,7 +20,7 @@ - * license in recognition of the original copyright. - * -- Alan Cox. - * -- * $Id: ipfwadm_core.c,v 1.1.1.4 2003/10/14 08:09:33 sparq Exp $ -+ * $Id: ipfwadm_core.c,v 1.9.2.2 2002/01/24 15:50:42 davem Exp $ - * - * Ported from BSD to Linux, - * Alan Cox 22/Nov/1994. -@@ -1205,6 +1205,7 @@ - ) - { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) -+ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ - int reset = 0; - #endif - return ip_chain_procinfo(IP_FW_ACCT, buffer,start, offset,length, -@@ -1223,6 +1224,7 @@ - ) - { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) -+ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ - int reset = 0; - #endif - return ip_chain_procinfo(IP_FW_IN, buffer,start,offset,length, -@@ -1237,6 +1239,7 @@ - ) - { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) -+ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ - int reset = 0; - #endif - return ip_chain_procinfo(IP_FW_OUT, buffer,start,offset,length, -@@ -1251,6 +1254,7 @@ - ) - { - #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) -+ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ - int reset = 0; - #endif - return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length, -diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_ECN.c src/linux/linux.stock/net/ipv4/netfilter/ipt_ECN.c ---- src/linux/linux/net/ipv4/netfilter/ipt_ECN.c 2003-10-14 04:02:57.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ipt_ECN.c 2004-05-09 04:13:03.000000000 -0400 -@@ -87,8 +87,8 @@ - } - - if (diffs[0] != *tcpflags) { -- diffs[0] = diffs[0] ^ 0xFFFF; -- diffs[1] = *tcpflags; -+ diffs[0] = htons(diffs[0]) ^ 0xFFFF; -+ diffs[1] = htons(*tcpflags); - tcph->check = csum_fold(csum_partial((char *)diffs, - sizeof(diffs), - tcph->check^0xFFFF)); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_LOG.c src/linux/linux.stock/net/ipv4/netfilter/ipt_LOG.c ---- src/linux/linux/net/ipv4/netfilter/ipt_LOG.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ipt_LOG.c 2004-05-09 04:13:03.000000000 -0400 -@@ -14,11 +14,15 @@ - #include - #include - -+#if 0 -+#define DEBUGP printk -+#else - #define DEBUGP(format, args...) -+#endif - - struct esphdr { - __u32 spi; --}; -+}; /* FIXME evil kludge */ - - /* Use lock to serialize, so printks don't overlap */ - static spinlock_t log_lock = SPIN_LOCK_UNLOCKED; -diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_REJECT.c src/linux/linux.stock/net/ipv4/netfilter/ipt_REJECT.c ---- src/linux/linux/net/ipv4/netfilter/ipt_REJECT.c 2003-07-04 04:12:31.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ipt_REJECT.c 2004-05-09 04:13:03.000000000 -0400 -@@ -6,8 +6,6 @@ - #include - #include - #include --#include --#include - #include - #include - #include -@@ -16,7 +14,11 @@ - #include - #include - -+#if 0 -+#define DEBUGP printk -+#else - #define DEBUGP(format, args...) -+#endif - - /* If the original packet is part of a connection, but the connection - is not confirmed, our manufactured reply will not be associated -@@ -155,7 +157,6 @@ - static void send_unreach(struct sk_buff *skb_in, int code) - { - struct iphdr *iph; -- struct udphdr *udph; - struct icmphdr *icmph; - struct sk_buff *nskb; - u32 saddr; -@@ -167,6 +168,7 @@ - if (!rt) - return; - -+ /* FIXME: Use sysctl number. --RR */ - if (!xrlim_allow(&rt->u.dst, 1*HZ)) - return; - -@@ -184,19 +186,6 @@ - if (iph->frag_off&htons(IP_OFFSET)) - return; - -- /* if UDP checksum is set, verify it's correct */ -- if (iph->protocol == IPPROTO_UDP -- && skb_in->tail-(u8*)iph >= sizeof(struct udphdr)) { -- int datalen = skb_in->len - (iph->ihl<<2); -- udph = (struct udphdr *)((char *)iph + (iph->ihl<<2)); -- if (udph->check -- && csum_tcpudp_magic(iph->saddr, iph->daddr, -- datalen, IPPROTO_UDP, -- csum_partial((char *)udph, datalen, -- 0)) != 0) -- return; -- } -- - /* If we send an ICMP error to an ICMP error a mess would result.. */ - if (iph->protocol == IPPROTO_ICMP - && skb_in->tail-(u8*)iph >= sizeof(struct icmphdr)) { -@@ -271,6 +260,7 @@ - /* Copy as much of original packet as will fit */ - data = skb_put(nskb, - length - sizeof(struct iphdr) - sizeof(struct icmphdr)); -+ /* FIXME: won't work with nonlinear skbs --RR */ - memcpy(data, skb_in->nh.iph, - length - sizeof(struct iphdr) - sizeof(struct icmphdr)); - icmph->checksum = ip_compute_csum((unsigned char *)icmph, -diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_ULOG.c src/linux/linux.stock/net/ipv4/netfilter/ipt_ULOG.c ---- src/linux/linux/net/ipv4/netfilter/ipt_ULOG.c 2003-07-04 04:12:32.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ipt_ULOG.c 2004-05-09 04:13:03.000000000 -0400 -@@ -12,7 +12,6 @@ - * module loadtime -HW - * 2002/07/07 remove broken nflog_rcv() function -HW - * 2002/08/29 fix shifted/unshifted nlgroup bug -HW -- * 2002/10/30 fix uninitialized mac_len field - - * - * Released under the terms of the GPL - * -@@ -32,7 +31,7 @@ - * Specify, after how many clock ticks (intel: 100 per second) the queue - * should be flushed even if it is not full yet. - * -- * ipt_ULOG.c,v 1.22 2002/10/30 09:07:31 laforge Exp -+ * ipt_ULOG.c,v 1.21 2002/08/29 10:54:34 laforge Exp - */ - - #include -@@ -60,7 +59,12 @@ - #define ULOG_NL_EVENT 111 /* Harald's favorite number */ - #define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ - -+#if 0 -+#define DEBUGP(format, args...) printk(__FILE__ ":" __FUNCTION__ ":" \ -+ format, ## args) -+#else - #define DEBUGP(format, args...) -+#endif - - #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format, ## args); } while (0) - -@@ -220,8 +224,7 @@ - && in->hard_header_len <= ULOG_MAC_LEN) { - memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len); - pm->mac_len = in->hard_header_len; -- } else -- pm->mac_len = 0; -+ } - - if (in) - strncpy(pm->indev_name, in->name, sizeof(pm->indev_name)); -diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_multiport.c src/linux/linux.stock/net/ipv4/netfilter/ipt_multiport.c ---- src/linux/linux/net/ipv4/netfilter/ipt_multiport.c 2003-07-04 04:12:32.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ipt_multiport.c 2004-05-09 04:13:03.000000000 -0400 -@@ -8,7 +8,11 @@ - #include - #include - -+#if 0 -+#define duprintf(format, args...) printk(format , ## args) -+#else - #define duprintf(format, args...) -+#endif - - /* Returns 1 if the port is matched by the test, 0 otherwise. */ - static inline int -@@ -74,7 +78,7 @@ - - /* Must specify proto == TCP/UDP, no unknown flags or bad count */ - return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP) -- && !(ip->invflags & IPT_INV_PROTO) -+ && !(ip->flags & IPT_INV_PROTO) - && matchsize == IPT_ALIGN(sizeof(struct ipt_multiport)) - && (multiinfo->flags == IPT_MULTIPORT_SOURCE - || multiinfo->flags == IPT_MULTIPORT_DESTINATION -diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_pool.c src/linux/linux.stock/net/ipv4/netfilter/ipt_pool.c ---- src/linux/linux/net/ipv4/netfilter/ipt_pool.c 2003-07-04 04:12:32.000000000 -0400 -+++ src/linux/linux.stock/net/ipv4/netfilter/ipt_pool.c 1969-12-31 19:00:00.000000000 -0500 -@@ -1,71 +0,0 @@ --/* Kernel module to match an IP address pool. */ -- --#include --#include --#include -- --#include --#include --#include -- --static inline int match_pool( -- ip_pool_t index, -- __u32 addr, -- int inv --) { -- if (ip_pool_match(index, ntohl(addr))) -- inv = !inv; -- return inv; --} -- --static int match( -- const struct sk_buff *skb, -- const struct net_device *in, -- const struct net_device *out, -- const void *matchinfo, -- int offset, -- const void *hdr, -- u_int16_t datalen, -- int *hotdrop --) { -- const struct ipt_pool_info *info = matchinfo; -- const struct iphdr *iph = skb->nh.iph; -- -- if (info->src != IP_POOL_NONE && !match_pool(info->src, iph->saddr, -- info->flags&IPT_POOL_INV_SRC)) -- return 0; -- -- if (info->dst != IP_POOL_NONE && !match_pool(info->dst, iph->daddr, -- info->flags&IPT_POOL_INV_DST)) -- return 0; -- -- return 1; --} -- --static int checkentry( -- const char *tablename, -- const struct ipt_ip *ip, -- void *matchinfo, -- unsigned int matchsize, -- unsigned int hook_mask --) { -- if (matchsize != IPT_ALIGN(sizeof(struct ipt_pool_info))) -- return 0; -- return 1; --} -- --static struct ipt_match pool_match --= { { NULL, NULL }, "pool", &match, &checkentry, NULL, THIS_MODULE }; -- --static int __init init(void) --{ -- return ipt_register_match(&pool_match); --} -- --static void __exit fini(void) --{ -- ipt_unregister_match(&pool_match); --} -- --module_init(init); --module_exit(fini); -diff -Nurb src/linux/linux/net/ipv6/mcast.c src/linux/linux.stock/net/ipv6/mcast.c ---- src/linux/linux/net/ipv6/mcast.c 2003-10-14 04:09:34.000000000 -0400 -+++ src/linux/linux.stock/net/ipv6/mcast.c 2004-05-09 04:13:22.000000000 -0400 -@@ -5,7 +5,7 @@ - * Authors: - * Pedro Roque - * -- * $Id: mcast.c,v 1.1.1.4 2003/10/14 08:09:34 sparq Exp $ -+ * $Id: mcast.c,v 1.38 2001/08/15 07:36:31 davem Exp $ - * - * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c - * diff --git a/obsolete-buildroot/sources/openwrt-linux-sch_htb.patch b/obsolete-buildroot/sources/openwrt-linux-sch_htb.patch deleted file mode 100644 index f74168aeea..0000000000 --- a/obsolete-buildroot/sources/openwrt-linux-sch_htb.patch +++ /dev/null @@ -1,570 +0,0 @@ ---- src/linux/linux/net/sched/sch_htb.c 2003-10-14 01:09:35.000000000 -0700 -+++ src/linux/linux.2.4.26/net/sched/sch_htb.c 2004-05-10 00:05:51.000000000 -0700 -@@ -9,6 +9,8 @@ - * Authors: Martin Devera, - * - * Credits (in time order) for older HTB versions: -+ * Stef Coene -+ * HTB support at LARTC mailing list - * Ondrej Kraus, - * found missing INIT_QDISC(htb) - * Vladimir Smelhaus, Aamer Akhter, Bert Hubert -@@ -17,9 +19,13 @@ - * code review and helpful comments on shaping - * Tomasz Wrona, - * created test case so that I was able to fix nasty bug -+ * Wilfried Weissmann -+ * spotted bug in dequeue code and helped with fix -+ * Jiri Fojtasek -+ * fixed requeue routine - * and many others. thanks. - * -- * $Id: sch_htb.c,v 1.1.1.4 2003/10/14 08:09:35 sparq Exp $ -+ * $Id: sch_htb.c,v 1.25 2003/12/07 11:08:25 devik Exp devik $ - */ - #include - #include -@@ -71,16 +77,12 @@ - #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */ - #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock) - #define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock) --#define HTB_VER 0x30007 /* major must be matched with number suplied by TC as version */ -+#define HTB_VER 0x30010 /* major must be matched with number suplied by TC as version */ - - #if HTB_VER >> 16 != TC_HTB_PROTOVER - #error "Mismatched sch_htb.c and pkt_sch.h" - #endif - --/* temporary debug defines to be removed after beta stage */ --#define DEVIK_MEND(N) --#define DEVIK_MSTART(N) -- - /* debugging support; S is subsystem, these are defined: - 0 - netlink messages - 1 - enqueue -@@ -100,13 +102,16 @@ - from LSB - */ - #ifdef HTB_DEBUG --#define HTB_DBG(S,L,FMT,ARG...) if (((q->debug>>(2*S))&3) >= L) \ -+#define HTB_DBG_COND(S,L) (((q->debug>>(2*S))&3) >= L) -+#define HTB_DBG(S,L,FMT,ARG...) if (HTB_DBG_COND(S,L)) \ - printk(KERN_DEBUG FMT,##ARG) - #define HTB_CHCL(cl) BUG_TRAP((cl)->magic == HTB_CMAGIC) - #define HTB_PASSQ q, - #define HTB_ARGQ struct htb_sched *q, - #define static -+#undef __inline__ - #define __inline__ -+#undef inline - #define inline - #define HTB_CMAGIC 0xFEFAFEF1 - #define htb_safe_rb_erase(N,R) do { BUG_TRAP((N)->rb_color != -1); \ -@@ -114,6 +119,7 @@ - rb_erase(N,R); \ - (N)->rb_color = -1; } while (0) - #else -+#define HTB_DBG_COND(S,L) (0) - #define HTB_DBG(S,L,FMT,ARG...) - #define HTB_PASSQ - #define HTB_ARGQ -@@ -219,6 +225,9 @@ - /* time of nearest event per level (row) */ - unsigned long near_ev_cache[TC_HTB_MAXDEPTH]; - -+ /* cached value of jiffies in dequeue */ -+ unsigned long jiffies; -+ - /* whether we hit non-work conserving class during this dequeue; we use */ - int nwc_hit; /* this to disable mindelay complaint in dequeue */ - -@@ -297,7 +306,7 @@ - rules in it */ - if (skb->priority == sch->handle) - return HTB_DIRECT; /* X:0 (direct flow) selected */ -- if ((cl = htb_find(skb->priority,sch)) != NULL) -+ if ((cl = htb_find(skb->priority,sch)) != NULL && cl->level == 0) - return cl; - - tcf = q->filter_list; -@@ -338,7 +347,7 @@ - static void htb_debug_dump (struct htb_sched *q) - { - int i,p; -- printk(KERN_DEBUG "htb*g j=%lu\n",jiffies); -+ printk(KERN_DEBUG "htb*g j=%lu lj=%lu\n",jiffies,q->jiffies); - /* rows */ - for (i=TC_HTB_MAXDEPTH-1;i>=0;i--) { - printk(KERN_DEBUG "htb*r%d m=%x",i,q->row_mask[i]); -@@ -421,26 +430,24 @@ - if ((delay <= 0 || delay > cl->mbuffer) && net_ratelimit()) - printk(KERN_ERR "HTB: suspicious delay in wait_tree d=%ld cl=%X h=%d\n",delay,cl->classid,debug_hint); - #endif -- DEVIK_MSTART(9); -- cl->pq_key = jiffies + PSCHED_US2JIFFIE(delay); -- if (cl->pq_key == jiffies) -+ cl->pq_key = q->jiffies + PSCHED_US2JIFFIE(delay); -+ if (cl->pq_key == q->jiffies) - cl->pq_key++; - - /* update the nearest event cache */ -- if (q->near_ev_cache[cl->level] - cl->pq_key < 0x80000000) -+ if (time_after(q->near_ev_cache[cl->level], cl->pq_key)) - q->near_ev_cache[cl->level] = cl->pq_key; - - while (*p) { - struct htb_class *c; parent = *p; - c = rb_entry(parent, struct htb_class, pq_node); -- if (cl->pq_key - c->pq_key < 0x80000000) -+ if (time_after_eq(cl->pq_key, c->pq_key)) - p = &parent->rb_right; - else - p = &parent->rb_left; - } - rb_link_node(&cl->pq_node, parent, p); - rb_insert_color(&cl->pq_node, &q->wait_pq[cl->level]); -- DEVIK_MEND(9); - } - - /** -@@ -453,12 +460,14 @@ - { - rb_node_t *p; - if ((*n)->rb_right) { -+ /* child at right. use it or its leftmost ancestor */ - *n = (*n)->rb_right; - while ((*n)->rb_left) - *n = (*n)->rb_left; - return; - } - while ((p = (*n)->rb_parent) != NULL) { -+ /* if we've arrived from left child then we have next node */ - if (p->rb_left == *n) break; - *n = p; - } -@@ -602,7 +611,7 @@ - long toks; - - if ((toks = (cl->ctokens + *diff)) < ( --#ifdef HTB_HYSTERESIS -+#if HTB_HYSTERESIS - cl->cmode != HTB_CANT_SEND ? -cl->cbuffer : - #endif - 0)) { -@@ -610,7 +619,7 @@ - return HTB_CANT_SEND; - } - if ((toks = (cl->tokens + *diff)) >= ( --#ifdef HTB_HYSTERESIS -+#if HTB_HYSTERESIS - cl->cmode == HTB_CAN_SEND ? -cl->buffer : - #endif - 0)) -@@ -689,7 +698,6 @@ - struct htb_sched *q = (struct htb_sched *)sch->data; - struct htb_class *cl = htb_classify(skb,sch); - -- DEVIK_MSTART(0); - if (cl == HTB_DIRECT || !cl) { - /* enqueue to helper queue */ - if (q->direct_queue.qlen < q->direct_qlen && cl) { -@@ -698,25 +706,20 @@ - } else { - kfree_skb (skb); - sch->stats.drops++; -- DEVIK_MEND(0); - return NET_XMIT_DROP; - } - } else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) { - sch->stats.drops++; - cl->stats.drops++; -- DEVIK_MEND(0); - return NET_XMIT_DROP; - } else { - cl->stats.packets++; cl->stats.bytes += skb->len; -- DEVIK_MSTART(1); - htb_activate (q,cl); -- DEVIK_MEND(1); - } - - sch->q.qlen++; - sch->stats.packets++; sch->stats.bytes += skb->len; -- HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",cl?cl->classid:0,skb); -- DEVIK_MEND(0); -+ HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",(cl && cl != HTB_DIRECT)?cl->classid:0,skb); - return NET_XMIT_SUCCESS; - } - -@@ -725,16 +728,18 @@ - { - struct htb_sched *q = (struct htb_sched *)sch->data; - struct htb_class *cl = htb_classify(skb,sch); -+ struct sk_buff *tskb; - - if (cl == HTB_DIRECT || !cl) { - /* enqueue to helper queue */ - if (q->direct_queue.qlen < q->direct_qlen && cl) { -- __skb_queue_tail(&q->direct_queue, skb); -- q->direct_pkts++; -+ __skb_queue_head(&q->direct_queue, skb); - } else { -- kfree_skb (skb); -- sch->stats.drops++; -- return NET_XMIT_DROP; -+ __skb_queue_head(&q->direct_queue, skb); -+ tskb = __skb_dequeue_tail(&q->direct_queue); -+ kfree_skb (tskb); -+ sch->stats.drops++; -+ return NET_XMIT_CN; - } - } else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) { - sch->stats.drops++; -@@ -744,7 +749,7 @@ - htb_activate (q,cl); - - sch->q.qlen++; -- HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",cl?cl->classid:0,skb); -+ HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",(cl && cl != HTB_DIRECT)?cl->classid:0,skb); - return NET_XMIT_SUCCESS; - } - -@@ -819,7 +824,7 @@ - cl->classid, diff, - (unsigned long long) q->now, - (unsigned long long) cl->t_c, -- jiffies); -+ q->jiffies); - diff = 1000; - } - #endif -@@ -862,6 +867,7 @@ - * - * Scans event queue for pending events and applies them. Returns jiffies to - * next pending event (0 for no event in pq). -+ * Note: Aplied are events whose have cl->pq_key <= jiffies. - */ - static long htb_do_events(struct htb_sched *q,int level) - { -@@ -876,9 +882,9 @@ - while (p->rb_left) p = p->rb_left; - - cl = rb_entry(p, struct htb_class, pq_node); -- if (cl->pq_key - (jiffies+1) < 0x80000000) { -- HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - jiffies); -- return cl->pq_key - jiffies; -+ if (time_after(cl->pq_key, q->jiffies)) { -+ HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - q->jiffies); -+ return cl->pq_key - q->jiffies; - } - htb_safe_rb_erase(p,q->wait_pq+level); - diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0); -@@ -889,7 +895,7 @@ - cl->classid, diff, - (unsigned long long) q->now, - (unsigned long long) cl->t_c, -- jiffies); -+ q->jiffies); - diff = 1000; - } - #endif -@@ -916,6 +922,7 @@ - rb_node_t **pptr; - } stk[TC_HTB_MAXDEPTH],*sp = stk; - -+ BUG_TRAP(tree->rb_node); - sp->root = tree->rb_node; - sp->pptr = pptr; - -@@ -949,16 +956,36 @@ - htb_dequeue_tree(struct htb_sched *q,int prio,int level) - { - struct sk_buff *skb = NULL; -- //struct htb_sched *q = (struct htb_sched *)sch->data; - struct htb_class *cl,*start; - /* look initial class up in the row */ -- DEVIK_MSTART(6); - start = cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio); - - do { -- BUG_TRAP(cl && cl->un.leaf.q->q.qlen); if (!cl) return NULL; -+next: -+ BUG_TRAP(cl); -+ if (!cl) return NULL; - HTB_DBG(4,1,"htb_deq_tr prio=%d lev=%d cl=%X defic=%d\n", - prio,level,cl->classid,cl->un.leaf.deficit[level]); -+ -+ /* class can be empty - it is unlikely but can be true if leaf -+ qdisc drops packets in enqueue routine or if someone used -+ graft operation on the leaf since last dequeue; -+ simply deactivate and skip such class */ -+ if (unlikely(cl->un.leaf.q->q.qlen == 0)) { -+ struct htb_class *next; -+ htb_deactivate(q,cl); -+ -+ /* row/level might become empty */ -+ if ((q->row_mask[level] & (1 << prio)) == 0) -+ return NULL; -+ -+ next = htb_lookup_leaf (q->row[level]+prio, -+ prio,q->ptr[level]+prio); -+ if (cl == start) /* fix start if we just deleted it */ -+ start = next; -+ cl = next; -+ goto next; -+ } - - if (likely((skb = cl->un.leaf.q->dequeue(cl->un.leaf.q)) != NULL)) - break; -@@ -971,8 +998,6 @@ - cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio); - } while (cl != start); - -- DEVIK_MEND(6); -- DEVIK_MSTART(7); - if (likely(skb != NULL)) { - if ((cl->un.leaf.deficit[level] -= skb->len) < 0) { - HTB_DBG(4,2,"htb_next_cl oldptr=%p quant_add=%d\n", -@@ -984,11 +1009,8 @@ - gives us slightly better performance */ - if (!cl->un.leaf.q->q.qlen) - htb_deactivate (q,cl); -- DEVIK_MSTART(8); - htb_charge_class (q,cl,level,skb->len); -- DEVIK_MEND(8); - } -- DEVIK_MEND(7); - return skb; - } - -@@ -1002,9 +1024,8 @@ - printk(KERN_INFO "HTB delay %ld > 5sec\n", delay); - delay = 5*HZ; - } -- del_timer(&q->timer); -- q->timer.expires = jiffies + delay; -- add_timer(&q->timer); -+ /* why don't use jiffies here ? because expires can be in past */ -+ mod_timer(&q->timer, q->jiffies + delay); - sch->flags |= TCQ_F_THROTTLED; - sch->stats.overlimits++; - HTB_DBG(3,1,"htb_deq t_delay=%ld\n",delay); -@@ -1016,7 +1037,11 @@ - struct htb_sched *q = (struct htb_sched *)sch->data; - int level; - long min_delay; -+#ifdef HTB_DEBUG -+ int evs_used = 0; -+#endif - -+ q->jiffies = jiffies; - HTB_DBG(3,1,"htb_deq dircnt=%d qlen=%d\n",skb_queue_len(&q->direct_queue), - sch->q.qlen); - -@@ -1027,27 +1052,26 @@ - return skb; - } - -- DEVIK_MSTART(2); - if (!sch->q.qlen) goto fin; - PSCHED_GET_TIME(q->now); - -- min_delay = HZ*5; -+ min_delay = LONG_MAX; - q->nwc_hit = 0; - for (level = 0; level < TC_HTB_MAXDEPTH; level++) { - /* common case optimization - skip event handler quickly */ - int m; - long delay; -- DEVIK_MSTART(3); -- if (jiffies - q->near_ev_cache[level] < 0x80000000 || 0) { -+ if (time_after_eq(q->jiffies, q->near_ev_cache[level])) { - delay = htb_do_events(q,level); -- q->near_ev_cache[level] += delay ? delay : HZ; -+ q->near_ev_cache[level] = q->jiffies + (delay ? delay : HZ); -+#ifdef HTB_DEBUG -+ evs_used++; -+#endif - } else -- delay = q->near_ev_cache[level] - jiffies; -+ delay = q->near_ev_cache[level] - q->jiffies; - - if (delay && min_delay > delay) - min_delay = delay; -- DEVIK_MEND(3); -- DEVIK_MSTART(5); - m = ~q->row_mask[level]; - while (m != (int)(-1)) { - int prio = ffz (m); -@@ -1056,29 +1080,29 @@ - if (likely(skb != NULL)) { - sch->q.qlen--; - sch->flags &= ~TCQ_F_THROTTLED; -- DEVIK_MEND(5); - goto fin; - } - } -- DEVIK_MEND(5); - } -- DEVIK_MSTART(4); - #ifdef HTB_DEBUG -- if (!q->nwc_hit && min_delay >= 5*HZ && net_ratelimit()) { -- printk(KERN_ERR "HTB: mindelay=%ld, report it please !\n",min_delay); -- htb_debug_dump(q); -+ if (!q->nwc_hit && min_delay >= 10*HZ && net_ratelimit()) { -+ if (min_delay == LONG_MAX) { -+ printk(KERN_ERR "HTB: dequeue bug (%d,%lu,%lu), report it please !\n", -+ evs_used,q->jiffies,jiffies); -+ htb_debug_dump(q); -+ } else -+ printk(KERN_WARNING "HTB: mindelay=%ld, some class has " -+ "too small rate\n",min_delay); - } - #endif -- htb_delay_by (sch,min_delay); -- DEVIK_MEND(4); -+ htb_delay_by (sch,min_delay > 5*HZ ? 5*HZ : min_delay); - fin: -- HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,jiffies,skb); -- DEVIK_MEND(2); -+ HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,q->jiffies,skb); - return skb; - } - - /* try to drop from each class (by prio) until one succeed */ --static int htb_drop(struct Qdisc* sch) -+static unsigned int htb_drop(struct Qdisc* sch) - { - struct htb_sched *q = (struct htb_sched *)sch->data; - int prio; -@@ -1086,14 +1110,15 @@ - for (prio = TC_HTB_NUMPRIO - 1; prio >= 0; prio--) { - struct list_head *p; - list_for_each (p,q->drops+prio) { -- struct htb_class *cl = list_entry(p,struct htb_class, -- un.leaf.drop_list); -+ struct htb_class *cl = list_entry(p, struct htb_class, -+ un.leaf.drop_list); -+ unsigned int len; - if (cl->un.leaf.q->ops->drop && -- cl->un.leaf.q->ops->drop(cl->un.leaf.q)) { -+ (len = cl->un.leaf.q->ops->drop(cl->un.leaf.q))) { - sch->q.qlen--; - if (!cl->un.leaf.q->q.qlen) - htb_deactivate (q,cl); -- return 1; -+ return len; - } - } - } -@@ -1208,7 +1233,8 @@ - gopt.direct_pkts = q->direct_pkts; - - #ifdef HTB_DEBUG -- htb_debug_dump(q); -+ if (HTB_DBG_COND(0,2)) -+ htb_debug_dump(q); - #endif - gopt.version = HTB_VER; - gopt.rate2quantum = q->rate2quantum; -@@ -1289,6 +1315,9 @@ - return -ENOBUFS; - sch_tree_lock(sch); - if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) { -+ if (cl->prio_activity) -+ htb_deactivate ((struct htb_sched*)sch->data,cl); -+ - /* TODO: is it correct ? Why CBQ doesn't do it ? */ - sch->q.qlen -= (*old)->q.qlen; - qdisc_reset(*old); -@@ -1323,7 +1352,7 @@ - - while ((tp = *fl) != NULL) { - *fl = tp->next; -- tp->ops->destroy(tp); -+ tcf_destroy(tp); - } - } - -@@ -1371,11 +1400,16 @@ - #ifdef HTB_RATECM - del_timer_sync (&q->rttim); - #endif -+ /* This line used to be after htb_destroy_class call below -+ and surprisingly it worked in 2.4. But it must precede it -+ because filter need its target class alive to be able to call -+ unbind_filter on it (without Oops). */ -+ htb_destroy_filters(&q->filter_list); -+ - while (!list_empty(&q->root)) - htb_destroy_class (sch,list_entry(q->root.next, - struct htb_class,sibling)); - -- htb_destroy_filters(&q->filter_list); - __skb_queue_purge(&q->direct_queue); - MOD_DEC_USE_COUNT; - } -@@ -1438,12 +1472,13 @@ - parent = parentid == TC_H_ROOT ? NULL : htb_find (parentid,sch); - - hopt = RTA_DATA(tb[TCA_HTB_PARMS-1]); -- HTB_DBG(0,1,"htb_chg cl=%p, clid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum); -+ HTB_DBG(0,1,"htb_chg cl=%p(%X), clid=%X, parid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,classid,parentid,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum); - rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB-1]); - ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB-1]); - if (!rtab || !ctab) goto failure; - - if (!cl) { /* new class */ -+ struct Qdisc *new_q; - /* check for valid classid */ - if (!classid || TC_H_MAJ(classid^sch->handle) || htb_find(classid,sch)) - goto failure; -@@ -1467,6 +1502,10 @@ - cl->magic = HTB_CMAGIC; - #endif - -+ /* create leaf qdisc early because it uses kmalloc(GFP_KERNEL) -+ so that can't be used inside of sch_tree_lock -+ -- thanks to Karlis Peisenieks */ -+ new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); - sch_tree_lock(sch); - if (parent && !parent->level) { - /* turn parent into inner node */ -@@ -1485,8 +1524,7 @@ - memset (&parent->un.inner,0,sizeof(parent->un.inner)); - } - /* leaf (we) needs elementary qdisc */ -- if (!(cl->un.leaf.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops))) -- cl->un.leaf.q = &noop_qdisc; -+ cl->un.leaf.q = new_q ? new_q : &noop_qdisc; - - cl->classid = classid; cl->parent = parent; - -@@ -1514,11 +1552,11 @@ - if (!cl->level) { - cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum; - if (!hopt->quantum && cl->un.leaf.quantum < 1000) { -- printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.", cl->classid); -+ printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.\n", cl->classid); - cl->un.leaf.quantum = 1000; - } - if (!hopt->quantum && cl->un.leaf.quantum > 200000) { -- printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.", cl->classid); -+ printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.\n", cl->classid); - cl->un.leaf.quantum = 200000; - } - if (hopt->quantum) ---- src/linux/linux/include/net/pkt_cls.h 2003-07-04 01:12:28.000000000 -0700 -+++ src/linux/linux.2.4.26/include/net/pkt_cls.h 2004-05-10 22:21:40.000000000 -0700 -@@ -77,7 +77,11 @@ - return -1; - } - -- -+static inline void tcf_destroy(struct tcf_proto *tp) -+{ -+ tp->ops->destroy(tp); -+ kfree(tp); -+} - - extern int register_tcf_proto_ops(struct tcf_proto_ops *ops); - extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops); diff --git a/obsolete-buildroot/sources/openwrt-wrt54g-linux.config b/obsolete-buildroot/sources/openwrt-wrt54g-linux.config deleted file mode 100644 index 2c80db7c4e..0000000000 --- a/obsolete-buildroot/sources/openwrt-wrt54g-linux.config +++ /dev/null @@ -1,852 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_MIPS=y -CONFIG_MIPS32=y -# CONFIG_MIPS64 is not set - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -# CONFIG_KMOD is not set - -# -# Machine selection -# -# CONFIG_ACER_PICA_61 is not set -# CONFIG_MIPS_DB1000 is not set -# CONFIG_MIPS_DB1100 is not set -# CONFIG_MIPS_DB1500 is not set -# CONFIG_MIPS_PB1000 is not set -# CONFIG_MIPS_PB1100 is not set -# CONFIG_MIPS_PB1500 is not set -# CONFIG_BAGET_MIPS is not set -# CONFIG_CASIO_E55 is not set -# CONFIG_MIPS_COBALT is not set -# CONFIG_DECSTATION is not set -# CONFIG_MIPS_EV64120 is not set -# CONFIG_MIPS_EV96100 is not set -# CONFIG_MIPS_IVR is not set -# CONFIG_HP_LASERJET is not set -# CONFIG_IBM_WORKPAD is not set -# CONFIG_LASAT is not set -# CONFIG_MIPS_ITE8172 is not set -# CONFIG_MIPS_ATLAS is not set -# CONFIG_MIPS_MAGNUM_4000 is not set -# CONFIG_MIPS_MALTA is not set -# CONFIG_MIPS_SEAD is not set -# CONFIG_MOMENCO_OCELOT is not set -# CONFIG_MOMENCO_OCELOT_G is not set -# CONFIG_DDB5074 is not set -# CONFIG_DDB5476 is not set -# CONFIG_DDB5477 is not set -# CONFIG_NEC_OSPREY is not set -# CONFIG_NEC_EAGLE is not set -# CONFIG_OLIVETTI_M700 is not set -# CONFIG_NINO is not set -# CONFIG_SGI_IP22 is not set -# CONFIG_SGI_IP27 is not set -# CONFIG_SGI_IP32 is not set -# CONFIG_SIBYTE_SB1xxx_SOC is not set -CONFIG_MIPS_BRCM=y -CONFIG_BCM947XX=y -CONFIG_BCM4710=y -CONFIG_BCM4310=y -CONFIG_BCM4704=y -# CONFIG_BCM5365 is not set -# CONFIG_SNI_RM200_PCI is not set -# CONFIG_TOSHIBA_JMR3927 is not set -# CONFIG_VICTOR_MPC30X is not set -# CONFIG_ZAO_CAPCELLA is not set -# CONFIG_HIGHMEM is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs init=/etc/preinit noinitrd console=ttyS0,115200" -CONFIG_PCI=y -CONFIG_NONCOHERENT_IO=y -CONFIG_NEW_TIME_C=y -CONFIG_NEW_IRQ=y -CONFIG_HND=y -# CONFIG_MIPS_AU1000 is not set - -# -# CPU selection -# -CONFIG_CPU_MIPS32=y -# CONFIG_CPU_MIPS64 is not set -# CONFIG_CPU_R3000 is not set -# CONFIG_CPU_TX39XX is not set -# CONFIG_CPU_VR41XX is not set -# CONFIG_CPU_R4300 is not set -# CONFIG_CPU_R4X00 is not set -# CONFIG_CPU_TX49XX is not set -# CONFIG_CPU_R5000 is not set -# CONFIG_CPU_R5432 is not set -# CONFIG_CPU_R6000 is not set -# CONFIG_CPU_NEVADA is not set -# CONFIG_CPU_R8000 is not set -# CONFIG_CPU_R10000 is not set -# CONFIG_CPU_RM7000 is not set -# CONFIG_CPU_SB1 is not set -CONFIG_CPU_HAS_PREFETCH=y -# CONFIG_VTAG_ICACHE is not set -# CONFIG_64BIT_PHYS_ADDR is not set -# CONFIG_CPU_ADVANCED is not set -CONFIG_CPU_HAS_LLSC=y -# CONFIG_CPU_HAS_LLDSCD is not set -# CONFIG_CPU_HAS_WB is not set -CONFIG_CPU_HAS_SYNC=y - -# -# General setup -# -CONFIG_CPU_LITTLE_ENDIAN=y -CONFIG_NET=y -# CONFIG_PCI_NAMES is not set -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_TC is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_HOTPLUG=y - -# -# PCMCIA/CardBus support -# -# CONFIG_PCMCIA is not set - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -# CONFIG_HOTPLUG_PCI_ACPI is not set -# CONFIG_SYSVIPC is not set -# CONFIG_BSD_PROCESS_ACCT is not set -CONFIG_SYSCTL=y -# CONFIG_PRINT_SYSCALLS is not set -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -# CONFIG_MIPS32_COMPAT is not set -# CONFIG_MIPS32_O32 is not set -# CONFIG_MIPS32_N32 is not set -# CONFIG_BINFMT_ELF32 is not set -# CONFIG_BINFMT_MISC is not set -# CONFIG_PM is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_PARTITIONS=y -# CONFIG_MTD_CONCAT is not set -# CONFIG_MTD_REDBOOT_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=y -# CONFIG_MTD_BLOCK is not set -CONFIG_MTD_BLOCK_RO=y -# CONFIG_FTL is not set -# CONFIG_NFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=y -# CONFIG_MTD_JEDECPROBE is not set -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -# CONFIG_MTD_CFI_B1 is not set -CONFIG_MTD_CFI_B2=y -# CONFIG_MTD_CFI_B4 is not set -CONFIG_MTD_CFI_I1=y -# CONFIG_MTD_CFI_I2 is not set -# CONFIG_MTD_CFI_I4 is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -CONFIG_MTD_CFI_SSTSTD=y -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP is not set -# CONFIG_MTD_JEDEC is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_PHYSMAP is not set -CONFIG_MTD_BCM947XX=y -# CONFIG_MTD_PB1000 is not set -# CONFIG_MTD_PB1500 is not set -# CONFIG_MTD_PB1100 is not set -# CONFIG_MTD_CSTM_MIPS_IXX is not set -# CONFIG_MTD_OCELOT is not set -# CONFIG_MTD_LASAT is not set -# CONFIG_MTD_PCI is not set - -# -# Self-contained MTD device drivers -# -CONFIG_MTD_SFLASH=y -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC1000 is not set -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOCPROBE is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Parallel port support -# -# CONFIG_PARPORT is not set - -# -# Plug and Play configuration -# -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_MSYS is not set -# CONFIG_NOROOT is not set -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_CISS_SCSI_TAPE is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=y -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_BLK_STATS is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=m -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_NETSWAP=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -# CONFIG_IP_ROUTE_MULTIPATH is not set -CONFIG_IP_ROUTE_TOS=y -# CONFIG_IP_ROUTE_VERBOSE is not set -# CONFIG_IP_ROUTE_LARGE_TABLES is not set -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=y -CONFIG_IP_NF_FTP=y -CONFIG_IP_NF_H323=y -CONFIG_IP_NF_CONNTRACK_MARK=y -# CONFIG_IP_NF_AMANDA is not set -CONFIG_IP_NF_TFTP=y -CONFIG_IP_NF_IRC=y -CONFIG_IP_NF_CT_PROTO_GRE=y -CONFIG_IP_NF_PPTP=y -CONFIG_IP_NF_MMS=y -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=y -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_SET=m -CONFIG_IP_NF_SET_MAX=256 -CONFIG_IP_NF_SET_IPMAP=m -CONFIG_IP_NF_SET_PORTMAP=m -CONFIG_IP_NF_SET_MACIPMAP=m -CONFIG_IP_NF_SET_IPHASH=m -CONFIG_IP_NF_MATCH_QUOTA=m -CONFIG_IP_NF_POOL=m -CONFIG_IP_POOL_STATISTICS=y -CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_DSTLIMIT=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=y -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_CONDITION=m -# CONFIG_IP_NF_MATCH_RANDOM is not set -CONFIG_IP_NF_MATCH_PSD=m -# CONFIG_IP_NF_MATCH_OSF is not set -# CONFIG_IP_NF_MATCH_NTH is not set -CONFIG_IP_NF_MATCH_IPV4OPTIONS=m -# CONFIG_IP_NF_MATCH_FUZZY is not set -CONFIG_IP_NF_MATCH_RECENT=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -# CONFIG_IP_NF_MATCH_U32 is not set -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=y -# CONFIG_IP_NF_MATCH_REALM is not set -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=y -CONFIG_IP_NF_MATCH_CONNMARK=m -CONFIG_IP_NF_MATCH_CONNLIMIT=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_UNCLEAN=m -CONFIG_IP_NF_MATCH_STRING=m -# CONFIG_IP_NF_MATCH_OWNER is not set -CONFIG_IP_NF_FILTER=y -CONFIG_IP_NF_TARGET_REJECT=y -CONFIG_IP_NF_TARGET_NETLINK=m -CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP=m -CONFIG_IP_NF_TARGET_MIRROR=m -CONFIG_IP_NF_NAT=y -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=y -CONFIG_IP_NF_TARGET_REDIRECT=y -CONFIG_IP_NF_NAT_H323=y -# CONFIG_IP_NF_TARGET_SAME is not set -# CONFIG_IP_NF_TARGET_NETMAP is not set -CONFIG_IP_NF_NAT_PPTP=y -CONFIG_IP_NF_NAT_PROTO_GRE=y -# CONFIG_IP_NF_NAT_LOCAL is not set -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=y -CONFIG_IP_NF_NAT_MMS=y -CONFIG_IP_NF_NAT_FTP=y -CONFIG_IP_NF_NAT_TFTP=y -CONFIG_IP_NF_MANGLE=y -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=y -CONFIG_IP_NF_TARGET_IPMARK=m -CONFIG_IP_NF_TARGET_CLASSIFY=m -CONFIG_IP_NF_TARGET_LOG=y -CONFIG_IP_NF_TARGET_CONNMARK=m -CONFIG_IP_NF_TARGET_TTL=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=y -# CONFIG_IP_NF_RAW is not set -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_IPV6=m - -# -# IPv6: Netfilter Configuration -# -CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_LIMIT=m -CONFIG_IP6_NF_MATCH_MAC=m -# CONFIG_IP6_NF_MATCH_RANDOM is not set -# CONFIG_IP6_NF_MATCH_NTH is not set -# CONFIG_IP6_NF_MATCH_FUZZY is not set -# CONFIG_IP6_NF_MATCH_RT is not set -# CONFIG_IP6_NF_MATCH_OPTS is not set -# CONFIG_IP6_NF_MATCH_FRAG is not set -# CONFIG_IP6_NF_MATCH_HL is not set -CONFIG_IP6_NF_MATCH_MULTIPORT=m -CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_MARK=m -# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set -# CONFIG_IP6_NF_MATCH_AHESP is not set -CONFIG_IP6_NF_MATCH_LENGTH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_REJECT=m -# CONFIG_IP6_NF_TARGET_HL is not set -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_MARK=m -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set -CONFIG_VLAN_8021Q=y - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -CONFIG_BRIDGE=y -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -CONFIG_WAN_ROUTER=m -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_CSZ=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_POLICE=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -# CONFIG_IDE is not set -# CONFIG_BLK_DEV_IDE_MODES is not set -# CONFIG_BLK_DEV_HD is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# Broadcom HND network devices -# -CONFIG_HND=y -# CONFIG_IL is not set -CONFIG_ET=m -# CONFIG_ET_4413 is not set -CONFIG_ET_47XX=y -CONFIG_WL=m -CONFIG_WL_AP=y -CONFIG_WL_STA=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -# CONFIG_DUMMY is not set -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -# CONFIG_NET_PCI is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -# CONFIG_ACENIC is not set -# CONFIG_DL2K is not set -# CONFIG_E1000 is not set -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -# CONFIG_TIGON3 is not set -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -CONFIG_PPP_ASYNC=y -# CONFIG_PPP_SYNC_TTY is not set -CONFIG_PPP_DEFLATE=y -CONFIG_PPP_BSDCOMP=y -CONFIG_PPPOE=m -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y -# CONFIG_STRIP is not set -# CONFIG_WAVELAN is not set -# CONFIG_ARLAN is not set -# CONFIG_AIRONET4500 is not set -# CONFIG_AIRONET4500_NONCS is not set -# CONFIG_AIRONET4500_PROC is not set -# CONFIG_AIRO is not set -# CONFIG_HERMES is not set -# CONFIG_PLX_HERMES is not set -# CONFIG_PCI_HERMES is not set -CONFIG_NET_WIRELESS=y - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -CONFIG_SHAPER=m - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# -# Character devices -# -# CONFIG_VT is not set -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -# CONFIG_SERIAL_EXTENDED is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=128 - -# -# I2C support -# -# CONFIG_I2C is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set - -# -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks -# -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -# CONFIG_ACQUIRE_WDT is not set -# CONFIG_ADVANTECH_WDT is not set -# CONFIG_ALIM7101_WDT is not set -# CONFIG_SC520_WDT is not set -# CONFIG_PCWATCHDOG is not set -# CONFIG_EUROTECH_WDT is not set -# CONFIG_IB700_WDT is not set -# CONFIG_WAFER_WDT is not set -# CONFIG_I810_TCO is not set -# CONFIG_MIXCOMWD is not set -# CONFIG_60XX_WDT is not set -# CONFIG_SC1200_WDT is not set -CONFIG_SOFT_WATCHDOG=y -# CONFIG_W83877F_WDT is not set -# CONFIG_WDT is not set -# CONFIG_WDTPCI is not set -# CONFIG_MACHZ_WDT is not set -# CONFIG_INDYDOG is not set -# CONFIG_AMD7XX_TCO is not set -# CONFIG_AMD_PM768 is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set - -# -# File systems -# -CONFIG_BLKDEV_SWAP=m -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -# CONFIG_EXT3_FS is not set -# CONFIG_JBD is not set -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -CONFIG_JFFS2_FS=y -CONFIG_JFFS2_FS_DEBUG=0 -# CONFIG_JFFS2_BBC_ARMLIB is not set -CONFIG_JFFS2_BBC_LZO=y -CONFIG_JFFS2_BBC_LZARI=y -CONFIG_JFFS2_BBC_LZHD=y -CONFIG_JFFS2_BBC_LZSS=y -# CONFIG_CRAMFS is not set -CONFIG_SQUASHFS=y -# CONFIG_TMPFS is not set -CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -CONFIG_DEVFS_FS=y -CONFIG_DEVFS_MOUNT=y -# CONFIG_DEVFS_DEBUG is not set -# CONFIG_DEVPTS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_EXT2_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_ROOT_NFS is not set -CONFIG_SWAP_VIA_NFS=m -CONFIG_NETSWAP=y -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=m -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -# CONFIG_MSDOS_PARTITION is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -# CONFIG_EFI_PARTITION is not set -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB is not set - -# -# Support for USB gadgets -# -# CONFIG_USB_GADGET is not set - -# -# Bluetooth support -# -# CONFIG_BLUEZ is not set - -# -# Kernel hacking -# -CONFIG_CROSSCOMPILE=y -# CONFIG_KERNPROF is not set -# CONFIG_MCOUNT is not set -# CONFIG_DEBUG is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_MIPS_UNCACHED is not set -# CONFIG_KTRACE is not set -# CONFIG_HWSIM is not set - -# -# Library routines -# -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/obsolete-buildroot/sources/openwrt-wrt54g-linux.patch b/obsolete-buildroot/sources/openwrt-wrt54g-linux.patch deleted file mode 100644 index 37c1dd34fd..0000000000 --- a/obsolete-buildroot/sources/openwrt-wrt54g-linux.patch +++ /dev/null @@ -1,2521 +0,0 @@ -diff -Nurb src/linux/linux.orig/Makefile src/linux/linux/Makefile ---- src/linux/linux.orig/Makefile 2003-10-14 04:00:10.000000000 -0400 -+++ src/linux/linux/Makefile 2004-05-25 21:12:24.000000000 -0400 -@@ -17,7 +17,7 @@ - FINDHPATH = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net $(HPATH)/math-emu - - HOSTCC = gcc --HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -+HOSTCFLAGS = -Wall -Wstrict-prototypes -Os -fomit-frame-pointer - - CROSS_COMPILE = - -@@ -88,7 +88,7 @@ - - CPPFLAGS := -D__KERNEL__ -I$(HPATH) - --CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ -+CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ - -fno-strict-aliasing -fno-common - - # Turn on -pg to instrument the kernel with calls to mcount(). -diff -Nurb src/linux/linux.orig/arch/mips/brcm-boards/bcm947xx/setup.c src/linux/linux/arch/mips/brcm-boards/bcm947xx/setup.c ---- src/linux/linux.orig/arch/mips/brcm-boards/bcm947xx/setup.c 2003-11-11 09:08:46.000000000 -0500 -+++ src/linux/linux/arch/mips/brcm-boards/bcm947xx/setup.c 2004-05-25 21:12:24.000000000 -0400 -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #endif - - #include -@@ -160,37 +161,38 @@ - #ifdef CONFIG_MTD_PARTITIONS - - static struct mtd_partition bcm947xx_parts[] = { -- { name: "pmon", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ }, -+ { name: "pmon", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, }, - { name: "linux", offset: 0, size: 0, }, - { name: "rootfs", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ }, - { name: "nvram", offset: 0, size: 0, }, -+ { name: "OpenWrt", offset: 0, size: 0, }, - { name: NULL, }, - }; - --struct mtd_partition * __init --init_mtd_partitions(struct mtd_info *mtd, size_t size) -+ -+static int __init -+find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part) - { -- struct minix_super_block *minixsb; -- struct ext2_super_block *ext2sb; -- struct romfs_super_block *romfsb; - struct cramfs_super *cramfsb; -+ struct squashfs_super_block *squashfsb; - struct trx_header *trx; -+ - unsigned char buf[512]; - int off; - size_t len; - -- minixsb = (struct minix_super_block *) buf; -- ext2sb = (struct ext2_super_block *) buf; -- romfsb = (struct romfs_super_block *) buf; - cramfsb = (struct cramfs_super *) buf; -+ squashfsb = (struct squashfs_super_block *) buf; - trx = (struct trx_header *) buf; - -- /* Look at every 64 KB boundary */ -- for (off = 0; off < size; off += (64 * 1024)) { -+ part->offset = 0; -+ part->size = 0; -+ -+ for (off = 0; off < size; off += mtd->erasesize) { - memset(buf, 0xe5, sizeof(buf)); - - /* -- * Read block 0 to test for romfs and cramfs superblock -+ * Read block 0 to test for cramfs superblock - */ - if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || - len != sizeof(buf)) -@@ -198,75 +200,105 @@ - - /* Try looking at TRX header for rootfs offset */ - if (le32_to_cpu(trx->magic) == TRX_MAGIC) { -- bcm947xx_parts[1].offset = off; - if (le32_to_cpu(trx->offsets[1]) > off) - off = le32_to_cpu(trx->offsets[1]); - continue; - } - -- /* romfs is at block zero too */ -- if (romfsb->word0 == ROMSB_WORD0 && -- romfsb->word1 == ROMSB_WORD1) { -- printk(KERN_NOTICE -- "%s: romfs filesystem found at block %d\n", -- mtd->name, off / BLOCK_SIZE); -- goto done; -- } -- -- /* so is cramfs */ -+ /* need to find cramfs */ - if (cramfsb->magic == CRAMFS_MAGIC) { - printk(KERN_NOTICE - "%s: cramfs filesystem found at block %d\n", - mtd->name, off / BLOCK_SIZE); -- goto done; -- } - -- /* -- * Read block 1 to test for minix and ext2 superblock -- */ -- if (MTD_READ(mtd, off + BLOCK_SIZE, sizeof(buf), &len, buf) || -- len != sizeof(buf)) -- continue; -- -- /* Try minix */ -- if (minixsb->s_magic == MINIX_SUPER_MAGIC || -- minixsb->s_magic == MINIX_SUPER_MAGIC2) { -- printk(KERN_NOTICE -- "%s: Minix filesystem found at block %d\n", -- mtd->name, off / BLOCK_SIZE); -+ part->size = cramfsb->size; - goto done; - } - -- /* Try ext2 */ -- if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { -+ /* or squashfs */ -+ if (squashfsb->s_magic == SQUASHFS_MAGIC) { - printk(KERN_NOTICE -- "%s: ext2 filesystem found at block %d\n", -+ "%s: squashfs filesystem found at block %d\n", - mtd->name, off / BLOCK_SIZE); -+ part->size = squashfsb->bytes_used+2048; - goto done; - } -- } - -+ } - printk(KERN_NOTICE -- "%s: Couldn't find valid ROM disk image\n", -+ "%s: Couldn't find valid cramfs image\n", - mtd->name); -+ return -1; -+ -+done: -+ part->offset = off; -+ return 0; -+} -+ -+ -+struct mtd_partition * __init -+init_mtd_partitions(struct mtd_info *mtd, size_t size) -+{ -+ -+ bcm947xx_parts[0].offset=0; -+ bcm947xx_parts[0].size=256*1024; - -- done: - /* Find and size nvram */ - bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize); - bcm947xx_parts[3].size = size - bcm947xx_parts[3].offset; - - /* Find and size rootfs */ -- if (off < size) { -- bcm947xx_parts[2].offset = off; -- bcm947xx_parts[2].size = bcm947xx_parts[3].offset - bcm947xx_parts[2].offset; -- } -+ //if (off < size) { -+ // bcm947xx_parts[2].offset = off; -+ // bcm947xx_parts[2].size = bcm947xx_parts[3].offset - bcm947xx_parts[2].offset; -+ //} -+ -+ /* Find and size rootfs */ -+ find_root(mtd,size,&bcm947xx_parts[2]); -+ -+ - - /* Size linux (kernel and rootfs) */ -+ bcm947xx_parts[1].offset = bcm947xx_parts[0].size; - bcm947xx_parts[1].size = bcm947xx_parts[3].offset - bcm947xx_parts[1].offset; - -+ -+ -+ /* calculate leftover flash, and assign it to the jffs partition */ -+ size_t spot; -+ size_t len; -+ size_t mask; -+ // get the offset to the end of the root_fs -+ spot=bcm947xx_parts[2].offset+bcm947xx_parts[2].size; -+ // round it up to an erase size boundary -+ spot+=mtd->erasesize-1; -+ // mask the number to the boundary -+ mask=mtd->erasesize; -+ mask=mask-1; -+ mask=mask^0xffffffff; -+ spot&=mask; -+ // length = flashsize - start position - nvram size -+ len=size-spot; -+ len=len-bcm947xx_parts[3].size; -+ -+ -+ bcm947xx_parts[4].offset = spot; -+ bcm947xx_parts[4].size = len; -+ -+ -+ -+ - /* Size pmon */ - bcm947xx_parts[0].size = bcm947xx_parts[1].offset - bcm947xx_parts[0].offset; - -+ //int x; -+ //for(x=0; x<5; x++) { -+ // printk(KERN_NOTICE -+ // "Partition %d mask_flags %08x\n", -+ // x,bcm947xx_parts[x].mask_flags); -+ //} -+ -+ - return bcm947xx_parts; - } - -diff -Nurb src/linux/linux.orig/drivers/mtd/maps/bcm947xx-flash.c src/linux/linux/drivers/mtd/maps/bcm947xx-flash.c ---- src/linux/linux.orig/drivers/mtd/maps/bcm947xx-flash.c 2003-11-08 04:35:52.000000000 -0500 -+++ src/linux/linux/drivers/mtd/maps/bcm947xx-flash.c 2004-05-25 21:12:24.000000000 -0400 -@@ -82,7 +82,21 @@ - - void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) - { -+ //memcpy_fromio(to, map->map_priv_1 + from, len); -+ if (len==1) { - memcpy_fromio(to, map->map_priv_1 + from, len); -+ } else { -+ int i; -+ u16 *dest = (u16 *) to; -+ u16 *src = (u16 *) (map->map_priv_1 + from); -+ -+ for (i = 0; i < (len / 2); i++) { -+ dest[i] = src[i]; -+ } -+ -+ if (len & 1) -+ *((u8 *)dest+len-1) = src[i] & 0xff; -+ } - } - - void bcm947xx_map_write8(struct map_info *map, __u8 d, unsigned long adr) -diff -Nurb src/linux/linux.orig/drivers/net/Makefile src/linux/linux/drivers/net/Makefile ---- src/linux/linux.orig/drivers/net/Makefile 2004-02-12 21:35:15.000000000 -0500 -+++ src/linux/linux/drivers/net/Makefile 2004-05-25 21:12:24.000000000 -0400 -@@ -25,7 +25,7 @@ - list-multi := rcpci.o - rcpci-objs := rcpci45.o rclanmtl.o - --subdir-m += mac -+# subdir-m += mac - subdir-m += diag - - ifeq ($(CONFIG_HW_QOS),y) -diff -Nurb src/linux/linux.orig/fs/Config.in src/linux/linux/fs/Config.in ---- src/linux/linux.orig/fs/Config.in 2003-07-04 04:12:05.000000000 -0400 -+++ src/linux/linux/fs/Config.in 2004-05-25 21:13:03.000000000 -0400 -@@ -47,6 +47,7 @@ - int 'JFFS2 debugging verbosity (0 = quiet, 2 = noisy)' CONFIG_JFFS2_FS_DEBUG 0 - fi - tristate 'Compressed ROM file system support' CONFIG_CRAMFS -+tristate 'Squashed file system support' CONFIG_SQUASHFS - bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS - define_bool CONFIG_RAMFS y - -diff -Nurb src/linux/linux.orig/fs/Makefile src/linux/linux/fs/Makefile ---- src/linux/linux.orig/fs/Makefile 2003-07-04 04:12:05.000000000 -0400 -+++ src/linux/linux/fs/Makefile 2004-05-25 21:13:03.000000000 -0400 -@@ -68,6 +68,7 @@ - subdir-$(CONFIG_SUN_OPENPROMFS) += openpromfs - subdir-$(CONFIG_BEFS_FS) += befs - subdir-$(CONFIG_JFS_FS) += jfs -+subdir-$(CONFIG_SQUASHFS) += squashfs - - - obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o -diff -Nurb src/linux/linux.orig/fs/squashfs/Makefile src/linux/linux/fs/squashfs/Makefile ---- src/linux/linux.orig/fs/squashfs/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/fs/squashfs/Makefile 2004-05-25 21:13:03.000000000 -0400 -@@ -0,0 +1,11 @@ -+# -+# Makefile for the linux squashfs routines. -+# -+ -+O_TARGET := squashfs.o -+ -+obj-y := inode.o -+ -+obj-m := $(O_TARGET) -+ -+include $(TOPDIR)/Rules.make -diff -Nurb src/linux/linux.orig/fs/squashfs/inode.c src/linux/linux/fs/squashfs/inode.c ---- src/linux/linux.orig/fs/squashfs/inode.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/fs/squashfs/inode.c 2004-05-25 21:13:03.000000000 -0400 -@@ -0,0 +1,1515 @@ -+/* -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * Copyright (c) 2002, 2003, 2004 Phillip Lougher -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * Squashfs - a compressed read only filesystem for Linux -+ * -+ * inode.c -+ */ -+ -+#define SQUASHFS_1_0_COMPATIBILITY -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef SQUASHFS_TRACE -+#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args) -+#else -+#define TRACE(s, args...) {} -+#endif -+ -+#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args) -+ -+#define SERROR(s, args...) if(!silent) printk(KERN_ERR "SQUASHFS error: "s, ## args) -+#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args) -+ -+static struct super_block *squashfs_read_super(struct super_block *, void *, int); -+static void squashfs_put_super(struct super_block *); -+static int squashfs_statfs(struct super_block *, struct statfs *); -+static int squashfs_symlink_readpage(struct file *file, struct page *page); -+static int squashfs_readpage(struct file *file, struct page *page); -+static int squashfs_readpage4K(struct file *file, struct page *page); -+static int squashfs_readdir(struct file *, void *, filldir_t); -+static struct dentry *squashfs_lookup(struct inode *, struct dentry *); -+static unsigned int read_data(struct super_block *s, char *buffer, -+ unsigned int index, unsigned int length, int, unsigned int *next_index); -+static int squashfs_get_cached_block(struct super_block *s, char *buffer, -+ unsigned int block, unsigned int offset, int length, -+ unsigned int *next_block, unsigned int *next_offset); -+static struct inode *squashfs_iget(struct super_block *s, squashfs_inode inode); -+static unsigned int read_blocklist(struct inode *inode, int index, int readahead_blks, -+ char *block_list, char **block_p, unsigned int *bsize); -+static void squashfs_put_super(struct super_block *s); -+ -+#ifdef SQUASHFS_1_0_COMPATIBILITY -+static int squashfs_readpage_lessthan4K(struct file *file, struct page *page); -+static struct inode *squashfs_iget_1(struct super_block *s, squashfs_inode inode); -+static unsigned int read_blocklist_1(struct inode *inode, int index, int readahead_blks, -+ char *block_list, char **block_p, unsigned int *bsize); -+#endif -+ -+DECLARE_MUTEX(read_data_mutex); -+ -+static z_stream stream; -+ -+static DECLARE_FSTYPE_DEV(squashfs_fs_type, "squashfs", squashfs_read_super); -+ -+static unsigned char squashfs_filetype_table[] = { -+ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK -+}; -+ -+static struct super_operations squashfs_ops = { -+ statfs: squashfs_statfs, -+ put_super: squashfs_put_super, -+}; -+ -+static struct address_space_operations squashfs_symlink_aops = { -+ readpage: squashfs_symlink_readpage -+}; -+ -+static struct address_space_operations squashfs_aops = { -+ readpage: squashfs_readpage -+}; -+ -+static struct address_space_operations squashfs_aops_4K = { -+ readpage: squashfs_readpage4K -+}; -+ -+#ifdef SQUASHFS_1_0_COMPATIBILITY -+static struct address_space_operations squashfs_aops_lessthan4K = { -+ readpage: squashfs_readpage_lessthan4K -+}; -+#endif -+ -+static struct file_operations squashfs_dir_ops = { -+ read: generic_read_dir, -+ readdir: squashfs_readdir -+}; -+ -+static struct inode_operations squashfs_dir_inode_ops = { -+ lookup: squashfs_lookup -+}; -+ -+ -+static unsigned int read_data(struct super_block *s, char *buffer, -+ unsigned int index, unsigned int length, int datablock, unsigned int *next_index) -+{ -+ squashfs_sb_info *msBlk = &s->u.squashfs_sb; -+ struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >> msBlk->devblksize_log2) + 2]; -+ unsigned int offset = index & ((1 << msBlk->devblksize_log2) - 1); -+ unsigned int cur_index = index >> msBlk->devblksize_log2; -+ int bytes, avail_bytes, b, k; -+ char *c_buffer; -+ unsigned int compressed; -+ unsigned int c_byte = length; -+ -+ if(c_byte) { -+ bytes = msBlk->devblksize - offset; -+ if(datablock) { -+ c_buffer = (compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte)) ? msBlk->read_data : buffer; -+ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); -+ } else { -+ c_buffer = (compressed = SQUASHFS_COMPRESSED(c_byte)) ? msBlk->read_data : buffer; -+ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); -+ } -+ -+ TRACE("Block @ 0x%x, %scompressed size %d\n", index, compressed ? "" : "un", (unsigned int) c_byte); -+ -+ if(!(bh[0] = sb_getblk(s, cur_index))) -+ goto block_release; -+ for(b = 1; bytes < c_byte; b++) { -+ if(!(bh[b] = sb_getblk(s, ++cur_index))) -+ goto block_release; -+ bytes += msBlk->devblksize; -+ } -+ ll_rw_block(READ, b, bh); -+ } else { -+ unsigned short temp; -+ if(!(bh[0] = sb_bread(s, cur_index))) -+ goto read_failure; -+ -+ if(msBlk->devblksize - offset == 1) { -+ if(msBlk->swap) -+ ((unsigned char *) &temp)[1] = *((unsigned char *) (bh[0]->b_data + offset)); -+ else -+ ((unsigned char *) &temp)[0] = *((unsigned char *) (bh[0]->b_data + offset)); -+ brelse(bh[0]); -+ if(!(bh[0] = sb_bread(s, ++cur_index))) -+ goto read_failure; -+ if(msBlk->swap) -+ ((unsigned char *) &temp)[0] = *((unsigned char *) bh[0]->b_data); -+ else -+ ((unsigned char *) &temp)[1] = *((unsigned char *) bh[0]->b_data); -+ c_byte = temp; -+ offset = 1; -+ } -+ else { -+ if(msBlk->swap) { -+ unsigned short temp; -+ ((unsigned char *) &temp)[1] = *((unsigned char *) (bh[0]->b_data + offset)); -+ ((unsigned char *) &temp)[0] = *((unsigned char *) (bh[0]->b_data + offset + 1)); -+ c_byte = temp; -+ } else -+ c_byte = *((unsigned short *) (bh[0]->b_data + offset)); -+ offset += 2; -+ } -+ if(SQUASHFS_CHECK_DATA(msBlk->sBlk.flags)) { -+ if(offset == msBlk->devblksize) { -+ brelse(bh[0]); -+ if(!(bh[0] = sb_bread(s, ++cur_index))) -+ goto read_failure; -+ offset = 0; -+ } -+ if(*((unsigned char *) (bh[0]->b_data + offset)) != SQUASHFS_MARKER_BYTE) { -+ ERROR("Metadata block marker corrupt @ %x\n", index); -+ brelse(bh[0]); -+ return 0; -+ } -+ offset ++; -+ } -+ -+ bytes = msBlk->devblksize - offset; -+ if(datablock) { -+ c_buffer = (compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte)) ? msBlk->read_data : buffer; -+ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); -+ } else { -+ c_buffer = (compressed = SQUASHFS_COMPRESSED(c_byte)) ? msBlk->read_data : buffer; -+ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); -+ } -+ -+ TRACE("Block @ 0x%x, %scompressed size %d\n", index, compressed ? "" : "un", (unsigned int) c_byte); -+ -+ for(b = 1; bytes < c_byte; b++) { -+ if(!(bh[b] = sb_getblk(s, ++cur_index))) -+ goto block_release; -+ bytes += msBlk->devblksize; -+ } -+ ll_rw_block(READ, b - 1, bh + 1); -+ } -+ -+ if(compressed) -+ down(&read_data_mutex); -+ -+ for(bytes = 0, k = 0; k < b; k++) { -+ avail_bytes = (c_byte - bytes) > (msBlk->devblksize - offset) ? msBlk->devblksize - offset : c_byte - bytes; -+ wait_on_buffer(bh[k]); -+ memcpy(c_buffer + bytes, bh[k]->b_data + offset, avail_bytes); -+ bytes += avail_bytes; -+ offset = 0; -+ brelse(bh[k]); -+ } -+ -+ /* -+ * uncompress block -+ */ -+ if(compressed) { -+ int zlib_err; -+ -+ stream.next_in = c_buffer; -+ stream.avail_in = c_byte; -+ stream.next_out = buffer; -+ stream.avail_out = msBlk->read_size; -+ if(((zlib_err = zlib_inflateInit(&stream)) != Z_OK) || -+ ((zlib_err = zlib_inflate(&stream, Z_FINISH)) != Z_STREAM_END) || -+ ((zlib_err = zlib_inflateEnd(&stream)) != Z_OK)) { -+ ERROR("zlib_fs returned unexpected result 0x%x\n", zlib_err); -+ bytes = 0; -+ } else -+ bytes = stream.total_out; -+ up(&read_data_mutex); -+ } -+ -+ if(next_index) -+ *next_index = index + c_byte + (length ? 0 : (SQUASHFS_CHECK_DATA(msBlk->sBlk.flags) ? 3 : 2)); -+ -+ return bytes; -+ -+block_release: -+ while(--b >= 0) brelse(bh[b]); -+ -+read_failure: -+ ERROR("sb_bread failed reading block 0x%x\n", cur_index); -+ return 0; -+} -+ -+ -+static int squashfs_get_cached_block(struct super_block *s, char *buffer, -+ unsigned int block, unsigned int offset, int length, -+ unsigned int *next_block, unsigned int *next_offset) -+{ -+ squashfs_sb_info *msBlk = &s->u.squashfs_sb; -+ int n, i, bytes, return_length = length; -+ unsigned int next_index; -+ -+ TRACE("Entered squashfs_get_cached_block [%x:%x]\n", block, offset); -+ -+ for(;;) { -+ for(i = 0; i < SQUASHFS_CACHED_BLKS; i++) -+ if(msBlk->block_cache[i].block == block) -+ break; -+ -+ down(&msBlk->block_cache_mutex); -+ if(i == SQUASHFS_CACHED_BLKS) { -+ /* read inode header block */ -+ for(i = msBlk->next_cache, n = SQUASHFS_CACHED_BLKS; n ; n --, i = (i + 1) % SQUASHFS_CACHED_BLKS) -+ if(msBlk->block_cache[i].block != SQUASHFS_USED_BLK) -+ break; -+ if(n == 0) { -+ up(&msBlk->block_cache_mutex); -+ sleep_on(&msBlk->waitq); -+ continue; -+ } -+ msBlk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS; -+ -+ if(msBlk->block_cache[i].block == SQUASHFS_INVALID_BLK) { -+ if(!(msBlk->block_cache[i].data = (unsigned char *) -+ kmalloc(SQUASHFS_METADATA_SIZE, GFP_KERNEL))) { -+ ERROR("Failed to allocate cache block\n"); -+ up(&msBlk->block_cache_mutex); -+ return 0; -+ } -+ } -+ -+ msBlk->block_cache[i].block = SQUASHFS_USED_BLK; -+ up(&msBlk->block_cache_mutex); -+ if(!(msBlk->block_cache[i].length = read_data(s, msBlk->block_cache[i].data, block, 0, 0, -+ &next_index))) { -+ ERROR("Unable to read cache block [%x:%x]\n", block, offset); -+ return 0; -+ } -+ down(&msBlk->block_cache_mutex); -+ wake_up(&msBlk->waitq); -+ msBlk->block_cache[i].block = block; -+ msBlk->block_cache[i].next_index = next_index; -+ TRACE("Read cache block [%x:%x]\n", block, offset); -+ } -+ -+ if(msBlk->block_cache[i].block != block) { -+ up(&msBlk->block_cache_mutex); -+ continue; -+ } -+ -+ if((bytes = msBlk->block_cache[i].length - offset) >= length) { -+ if(buffer) -+ memcpy(buffer, msBlk->block_cache[i].data + offset, length); -+ if(msBlk->block_cache[i].length - offset == length) { -+ *next_block = msBlk->block_cache[i].next_index; -+ *next_offset = 0; -+ } else { -+ *next_block = block; -+ *next_offset = offset + length; -+ } -+ -+ up(&msBlk->block_cache_mutex); -+ return return_length; -+ } else { -+ if(buffer) { -+ memcpy(buffer, msBlk->block_cache[i].data + offset, bytes); -+ buffer += bytes; -+ } -+ block = msBlk->block_cache[i].next_index; -+ up(&msBlk->block_cache_mutex); -+ length -= bytes; -+ offset = 0; -+ } -+ } -+} -+ -+ -+static int get_fragment_location(struct super_block *s, unsigned int fragment, unsigned int *fragment_start_block, unsigned int *fragment_size) -+{ -+ squashfs_sb_info *msBlk = &s->u.squashfs_sb; -+ unsigned int start_block = msBlk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)]; -+ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment); -+ squashfs_fragment_entry fragment_entry; -+ -+ if(msBlk->swap) { -+ squashfs_fragment_entry sfragment_entry; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sfragment_entry, start_block, offset, -+ sizeof(sfragment_entry), &start_block, &offset)) -+ return 0; -+ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &fragment_entry, start_block, offset, -+ sizeof(fragment_entry), &start_block, &offset)) -+ return 0; -+ -+ *fragment_start_block = fragment_entry.start_block; -+ *fragment_size = fragment_entry.size; -+ -+ return 1; -+} -+ -+ -+void release_cached_fragment(squashfs_sb_info *msBlk, struct squashfs_fragment_cache *fragment) -+{ -+ down(&msBlk->fragment_mutex); -+ fragment->locked --; -+ wake_up(&msBlk->fragment_wait_queue); -+ up(&msBlk->fragment_mutex); -+} -+ -+ -+struct squashfs_fragment_cache *get_cached_fragment(struct super_block *s, unsigned int start_block, int length) -+{ -+ int i, n; -+ squashfs_sb_info *msBlk = &s->u.squashfs_sb; -+ -+ for(;;) { -+ down(&msBlk->fragment_mutex); -+ for(i = 0; i < SQUASHFS_CACHED_FRAGMENTS && msBlk->fragment[i].block != start_block; i++); -+ if(i == SQUASHFS_CACHED_FRAGMENTS) { -+ for(i = msBlk->next_fragment, n = SQUASHFS_CACHED_FRAGMENTS; -+ n && msBlk->fragment[i].locked; n--, i = (i + 1) % SQUASHFS_CACHED_FRAGMENTS); -+ -+ if(n == 0) { -+ up(&msBlk->fragment_mutex); -+ sleep_on(&msBlk->fragment_wait_queue); -+ continue; -+ } -+ msBlk->next_fragment = (msBlk->next_fragment + 1) % SQUASHFS_CACHED_FRAGMENTS; -+ -+ if(msBlk->fragment[i].data == NULL) -+ if(!(msBlk->fragment[i].data = (unsigned char *) -+ kmalloc(SQUASHFS_FILE_MAX_SIZE, GFP_KERNEL))) { -+ ERROR("Failed to allocate fragment cache block\n"); -+ up(&msBlk->fragment_mutex); -+ return NULL; -+ } -+ -+ msBlk->fragment[i].block = SQUASHFS_INVALID_BLK; -+ msBlk->fragment[i].locked = 1; -+ up(&msBlk->fragment_mutex); -+ if(!(msBlk->fragment[i].length = read_data(s, msBlk->fragment[i].data, start_block, length, -+ 1, NULL))) { -+ ERROR("Unable to read fragment cache block [%x]\n", start_block); -+ msBlk->fragment[i].locked = 0; -+ return NULL; -+ } -+ msBlk->fragment[i].block = start_block; -+ TRACE("New fragment %d, start block %d, locked %d\n", i, msBlk->fragment[i].block, msBlk->fragment[i].locked); -+ return &msBlk->fragment[i]; -+ } -+ -+ msBlk->fragment[i].locked ++; -+ up(&msBlk->fragment_mutex); -+ -+ TRACE("Got fragment %d, start block %d, locked %d\n", i, msBlk->fragment[i].block, msBlk->fragment[i].locked); -+ return &msBlk->fragment[i]; -+ } -+} -+ -+ -+#ifdef SQUASHFS_1_0_COMPATIBILITY -+static struct inode *squashfs_iget_1(struct super_block *s, squashfs_inode inode) -+{ -+ struct inode *i = new_inode(s); -+ squashfs_sb_info *msBlk = &s->u.squashfs_sb; -+ squashfs_super_block *sBlk = &msBlk->sBlk; -+ unsigned int block = SQUASHFS_INODE_BLK(inode) + sBlk->inode_table_start; -+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); -+ unsigned int next_block, next_offset; -+ squashfs_base_inode_header_1 inodeb; -+ -+ TRACE("Entered squashfs_iget_1\n"); -+ -+ if(msBlk->swap) { -+ squashfs_base_inode_header_1 sinodeb; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodeb, block, offset, -+ sizeof(sinodeb), &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_BASE_INODE_HEADER_1(&inodeb, &sinodeb, sizeof(sinodeb)); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodeb, block, offset, -+ sizeof(inodeb), &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_nlink = 1; -+ -+ i->i_mtime = sBlk->mkfs_time; -+ i->i_atime = sBlk->mkfs_time; -+ i->i_ctime = sBlk->mkfs_time; -+ -+ if(inodeb.inode_type != SQUASHFS_IPC_TYPE) -+ i->i_uid = msBlk->uid[((inodeb.inode_type - 1) / SQUASHFS_TYPES) * 16 + inodeb.uid]; -+ i->i_ino = SQUASHFS_MK_VFS_INODE(block - sBlk->inode_table_start, offset); -+ -+ i->i_mode = inodeb.mode; -+ -+ switch(inodeb.inode_type == SQUASHFS_IPC_TYPE ? SQUASHFS_IPC_TYPE : (inodeb.inode_type - 1) % SQUASHFS_TYPES + 1) { -+ case SQUASHFS_FILE_TYPE: { -+ squashfs_reg_inode_header_1 inodep; -+ -+ if(msBlk->swap) { -+ squashfs_reg_inode_header_1 sinodep; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_REG_INODE_HEADER_1(&inodep, &sinodep); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_size = inodep.file_size; -+ i->i_fop = &generic_ro_fops; -+ if(sBlk->block_size > 4096) -+ i->i_data.a_ops = &squashfs_aops; -+ else if(sBlk->block_size == 4096) -+ i->i_data.a_ops = &squashfs_aops_4K; -+ else -+ i->i_data.a_ops = &squashfs_aops_lessthan4K; -+ i->i_mode |= S_IFREG; -+ i->i_mtime = inodep.mtime; -+ i->i_atime = inodep.mtime; -+ i->i_ctime = inodep.mtime; -+ i->i_blocks = ((i->i_size - 1) >> 9) + 1; -+ i->i_blksize = PAGE_CACHE_SIZE; -+ i->u.squashfs_i.fragment_start_block = SQUASHFS_INVALID_BLK; -+ i->u.squashfs_i.fragment_offset = 0; -+ i->u.squashfs_i.start_block = inodep.start_block; -+ i->u.squashfs_i.block_list_start = next_block; -+ i->u.squashfs_i.offset = next_offset; -+ TRACE("File inode %x:%x, start_block %x, block_list_start %x, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, inodep.start_block, next_block, next_offset); -+ break; -+ } -+ case SQUASHFS_DIR_TYPE: { -+ squashfs_dir_inode_header_1 inodep; -+ -+ if(msBlk->swap) { -+ squashfs_dir_inode_header_1 sinodep; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DIR_INODE_HEADER_1(&inodep, &sinodep); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_size = inodep.file_size; -+ i->i_op = &squashfs_dir_inode_ops; -+ i->i_fop = &squashfs_dir_ops; -+ i->i_mode |= S_IFDIR; -+ i->i_mtime = inodep.mtime; -+ i->i_atime = inodep.mtime; -+ i->i_ctime = inodep.mtime; -+ i->u.squashfs_i.start_block = inodep.start_block; -+ i->u.squashfs_i.offset = inodep.offset; -+ TRACE("Directory inode %x:%x, start_block %x, offset %x\n", SQUASHFS_INODE_BLK(inode), offset, -+ inodep.start_block, inodep.offset); -+ break; -+ } -+ case SQUASHFS_SYMLINK_TYPE: { -+ squashfs_symlink_inode_header_1 inodep; -+ -+ if(msBlk->swap) { -+ squashfs_symlink_inode_header_1 sinodep; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(&inodep, &sinodep); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_size = inodep.symlink_size; -+ i->i_op = &page_symlink_inode_operations; -+ i->i_data.a_ops = &squashfs_symlink_aops; -+ i->i_mode |= S_IFLNK; -+ i->u.squashfs_i.start_block = next_block; -+ i->u.squashfs_i.offset = next_offset; -+ TRACE("Symbolic link inode %x:%x, start_block %x, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, next_block, next_offset); -+ break; -+ } -+ case SQUASHFS_BLKDEV_TYPE: -+ case SQUASHFS_CHRDEV_TYPE: { -+ squashfs_dev_inode_header_1 inodep; -+ -+ if(msBlk->swap) { -+ squashfs_dev_inode_header_1 sinodep; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DEV_INODE_HEADER_1(&inodep, &sinodep); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_size = 0; -+ i->i_mode |= (inodeb.inode_type == SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : S_IFBLK; -+ init_special_inode(i, i->i_mode, inodep.rdev); -+ TRACE("Device inode %x:%x, rdev %x\n", SQUASHFS_INODE_BLK(inode), offset, inodep.rdev); -+ break; -+ } -+ case SQUASHFS_IPC_TYPE: { -+ squashfs_ipc_inode_header_1 inodep; -+ -+ if(msBlk->swap) { -+ squashfs_ipc_inode_header_1 sinodep; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_IPC_INODE_HEADER_1(&inodep, &sinodep); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_size = 0; -+ i->i_mode |= (inodep.type == SQUASHFS_FIFO_TYPE) ? S_IFIFO : S_IFSOCK; -+ i->i_uid = msBlk->uid[inodep.offset * 16 + inodeb.uid]; -+ init_special_inode(i, i->i_mode, 0); -+ break; -+ } -+ default: -+ ERROR("Unknown inode type %d in squashfs_iget!\n", inodeb.inode_type); -+ goto failed_read1; -+ } -+ -+ if(inodeb.guid == SQUASHFS_GUIDS) -+ i->i_gid = i->i_uid; -+ else -+ i->i_gid = msBlk->guid[inodeb.guid]; -+ -+ return i; -+ -+failed_read: -+ ERROR("Unable to read inode [%x:%x]\n", block, offset); -+ -+failed_read1: -+ return NULL; -+} -+#endif -+ -+ -+static struct inode *squashfs_iget(struct super_block *s, squashfs_inode inode) -+{ -+ struct inode *i = new_inode(s); -+ squashfs_sb_info *msBlk = &s->u.squashfs_sb; -+ squashfs_super_block *sBlk = &msBlk->sBlk; -+ unsigned int block = SQUASHFS_INODE_BLK(inode) + sBlk->inode_table_start; -+ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); -+ unsigned int next_block, next_offset; -+ squashfs_base_inode_header inodeb; -+ -+ TRACE("Entered squashfs_iget\n"); -+ -+ if(msBlk->swap) { -+ squashfs_base_inode_header sinodeb; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodeb, block, offset, -+ sizeof(sinodeb), &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_BASE_INODE_HEADER(&inodeb, &sinodeb, sizeof(sinodeb)); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodeb, block, offset, -+ sizeof(inodeb), &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_nlink = 1; -+ -+ i->i_mtime = sBlk->mkfs_time; -+ i->i_atime = sBlk->mkfs_time; -+ i->i_ctime = sBlk->mkfs_time; -+ -+ if(inodeb.inode_type != SQUASHFS_IPC_TYPE) -+ i->i_uid = msBlk->uid[((inodeb.inode_type - 1) / SQUASHFS_TYPES) * 16 + inodeb.uid]; -+ i->i_ino = SQUASHFS_MK_VFS_INODE(block - sBlk->inode_table_start, offset); -+ -+ i->i_mode = inodeb.mode; -+ -+ switch(inodeb.inode_type) { -+ case SQUASHFS_FILE_TYPE: { -+ squashfs_reg_inode_header inodep; -+ -+ if(msBlk->swap) { -+ squashfs_reg_inode_header sinodep; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_REG_INODE_HEADER(&inodep, &sinodep); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->u.squashfs_i.fragment_start_block = SQUASHFS_INVALID_BLK; -+ if(inodep.fragment != SQUASHFS_INVALID_BLK && !get_fragment_location(s, inodep.fragment, -+ &i->u.squashfs_i.fragment_start_block, &i->u.squashfs_i.fragment_size)) -+ goto failed_read; -+ -+ i->u.squashfs_i.fragment_offset = inodep.offset; -+ i->i_size = inodep.file_size; -+ i->i_fop = &generic_ro_fops; -+ if(sBlk->block_size > 4096) -+ i->i_data.a_ops = &squashfs_aops; -+ else -+ i->i_data.a_ops = &squashfs_aops_4K; -+ i->i_mode |= S_IFREG; -+ i->i_mtime = inodep.mtime; -+ i->i_atime = inodep.mtime; -+ i->i_ctime = inodep.mtime; -+ i->i_blocks = ((i->i_size - 1) >> 9) + 1; -+ i->i_blksize = PAGE_CACHE_SIZE; -+ i->u.squashfs_i.start_block = inodep.start_block; -+ i->u.squashfs_i.block_list_start = next_block; -+ i->u.squashfs_i.offset = next_offset; -+ TRACE("File inode %x:%x, start_block %x, block_list_start %x, offset %x fragment_index %x fragment_offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, inodep.start_block, next_block, next_offset, inodep.fragment, inodep.offset); -+ break; -+ } -+ case SQUASHFS_DIR_TYPE: { -+ squashfs_dir_inode_header inodep; -+ -+ if(msBlk->swap) { -+ squashfs_dir_inode_header sinodep; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DIR_INODE_HEADER(&inodep, &sinodep); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_size = inodep.file_size; -+ i->i_op = &squashfs_dir_inode_ops; -+ i->i_fop = &squashfs_dir_ops; -+ i->i_mode |= S_IFDIR; -+ i->i_mtime = inodep.mtime; -+ i->i_atime = inodep.mtime; -+ i->i_ctime = inodep.mtime; -+ i->u.squashfs_i.start_block = inodep.start_block; -+ i->u.squashfs_i.offset = inodep.offset; -+ TRACE("Directory inode %x:%x, start_block %x, offset %x\n", SQUASHFS_INODE_BLK(inode), offset, -+ inodep.start_block, inodep.offset); -+ break; -+ } -+ case SQUASHFS_SYMLINK_TYPE: { -+ squashfs_symlink_inode_header inodep; -+ -+ if(msBlk->swap) { -+ squashfs_symlink_inode_header sinodep; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(&inodep, &sinodep); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_size = inodep.symlink_size; -+ i->i_op = &page_symlink_inode_operations; -+ i->i_data.a_ops = &squashfs_symlink_aops; -+ i->i_mode |= S_IFLNK; -+ i->u.squashfs_i.start_block = next_block; -+ i->u.squashfs_i.offset = next_offset; -+ TRACE("Symbolic link inode %x:%x, start_block %x, offset %x\n", -+ SQUASHFS_INODE_BLK(inode), offset, next_block, next_offset); -+ break; -+ } -+ case SQUASHFS_BLKDEV_TYPE: -+ case SQUASHFS_CHRDEV_TYPE: { -+ squashfs_dev_inode_header inodep; -+ -+ if(msBlk->swap) { -+ squashfs_dev_inode_header sinodep; -+ -+ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ SQUASHFS_SWAP_DEV_INODE_HEADER(&inodep, &sinodep); -+ } else -+ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), -+ &next_block, &next_offset)) -+ goto failed_read; -+ -+ i->i_size = 0; -+ i->i_mode |= (inodeb.inode_type == SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : S_IFBLK; -+ init_special_inode(i, i->i_mode, inodep.rdev); -+ TRACE("Device inode %x:%x, rdev %x\n", SQUASHFS_INODE_BLK(inode), offset, inodep.rdev); -+ break; -+ } -+ case SQUASHFS_FIFO_TYPE: -+ case SQUASHFS_SOCKET_TYPE: { -+ i->i_size = 0; -+ i->i_mode |= (inodeb.inode_type == SQUASHFS_FIFO_TYPE) ? S_IFIFO : S_IFSOCK; -+ init_special_inode(i, i->i_mode, 0); -+ break; -+ } -+ default: -+ ERROR("Unknown inode type %d in squashfs_iget!\n", inodeb.inode_type); -+ goto failed_read1; -+ } -+ -+ if(inodeb.guid == SQUASHFS_GUIDS) -+ i->i_gid = i->i_uid; -+ else -+ i->i_gid = msBlk->guid[inodeb.guid]; -+ -+ return i; -+ -+failed_read: -+ ERROR("Unable to read inode [%x:%x]\n", block, offset); -+ -+failed_read1: -+ return NULL; -+} -+ -+ -+static struct super_block *squashfs_read_super(struct super_block *s, -+ void *data, int silent) -+{ -+ kdev_t dev = s->s_dev; -+ squashfs_sb_info *msBlk = &s->u.squashfs_sb; -+ squashfs_super_block *sBlk = &msBlk->sBlk; -+ int i; -+ -+ TRACE("Entered squashfs_read_superblock\n"); -+ -+ msBlk->devblksize = get_hardsect_size(dev); -+ if(msBlk->devblksize < BLOCK_SIZE) -+ msBlk->devblksize = BLOCK_SIZE; -+ msBlk->devblksize_log2 = ffz(~msBlk->devblksize); -+ set_blocksize(dev, msBlk->devblksize); -+ s->s_blocksize = msBlk->devblksize; -+ s->s_blocksize_bits = msBlk->devblksize_log2; -+ -+ init_MUTEX(&msBlk->read_page_mutex); -+ init_MUTEX(&msBlk->block_cache_mutex); -+ init_MUTEX(&msBlk->fragment_mutex); -+ -+ init_waitqueue_head(&msBlk->waitq); -+ init_waitqueue_head(&msBlk->fragment_wait_queue); -+ -+ if(!read_data(s, (char *) sBlk, SQUASHFS_START, sizeof(squashfs_super_block) | SQUASHFS_COMPRESSED_BIT, 0, NULL)) { -+ SERROR("unable to read superblock\n"); -+ goto failed_mount; -+ } -+ -+ /* Check it is a SQUASHFS superblock */ -+ msBlk->swap = 0; -+ if((s->s_magic = sBlk->s_magic) != SQUASHFS_MAGIC) { -+ if(sBlk->s_magic == SQUASHFS_MAGIC_SWAP) { -+ squashfs_super_block sblk; -+ WARNING("Mounting a different endian SQUASHFS filesystem on %s\n", bdevname(dev)); -+ SQUASHFS_SWAP_SUPER_BLOCK(&sblk, sBlk); -+ memcpy(sBlk, &sblk, sizeof(squashfs_super_block)); -+ msBlk->swap = 1; -+ } else { -+ SERROR("Can't find a SQUASHFS superblock on %s\n", bdevname(dev)); -+ goto failed_mount; -+ } -+ } -+ -+ /* Check the MAJOR & MINOR versions */ -+#ifdef SQUASHFS_1_0_COMPATIBILITY -+ if((sBlk->s_major != 1) && (sBlk->s_major != 2 || sBlk->s_minor > SQUASHFS_MINOR)) { -+ SERROR("Major/Minor mismatch, filesystem is (%d:%d), I support (1 : x) or (2 : <= %d)\n", -+ sBlk->s_major, sBlk->s_minor, SQUASHFS_MINOR); -+ goto failed_mount; -+ } -+ if(sBlk->s_major == 1) -+ sBlk->block_size = sBlk->block_size_1; -+#else -+ if(sBlk->s_major != SQUASHFS_MAJOR || sBlk->s_minor > SQUASHFS_MINOR) { -+ SERROR("Major/Minor mismatch, filesystem is (%d:%d), I support (%d: <= %d)\n", -+ sBlk->s_major, sBlk->s_minor, SQUASHFS_MAJOR, SQUASHFS_MINOR); -+ goto failed_mount; -+ } -+#endif -+ -+ TRACE("Found valid superblock on %s\n", bdevname(dev)); -+ TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : ""); -+ TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sBlk->flags) ? "un" : ""); -+ TRACE("Check data is %s present in the filesystem\n", SQUASHFS_CHECK_DATA(sBlk->flags) ? "" : "not"); -+ TRACE("Filesystem size %d bytes\n", sBlk->bytes_used); -+ TRACE("Block size %d\n", sBlk->block_size); -+ TRACE("Number of inodes %d\n", sBlk->inodes); -+ if(sBlk->s_major > 1) -+ TRACE("Number of fragments %d\n", sBlk->fragments); -+ TRACE("Number of uids %d\n", sBlk->no_uids); -+ TRACE("Number of gids %d\n", sBlk->no_guids); -+ TRACE("sBlk->inode_table_start %x\n", sBlk->inode_table_start); -+ TRACE("sBlk->directory_table_start %x\n", sBlk->directory_table_start); -+ if(sBlk->s_major > 1) -+ TRACE("sBlk->fragment_table_start %x\n", sBlk->fragment_table_start); -+ TRACE("sBlk->uid_start %x\n", sBlk->uid_start); -+ -+ s->s_flags |= MS_RDONLY; -+ s->s_op = &squashfs_ops; -+ -+ /* Init inode_table block pointer array */ -+ if(!(msBlk->block_cache = (squashfs_cache *) kmalloc(sizeof(squashfs_cache) * SQUASHFS_CACHED_BLKS, GFP_KERNEL))) { -+ ERROR("Failed to allocate block cache\n"); -+ goto failed_mount; -+ } -+ -+ for(i = 0; i < SQUASHFS_CACHED_BLKS; i++) -+ msBlk->block_cache[i].block = SQUASHFS_INVALID_BLK; -+ -+ msBlk->next_cache = 0; -+ -+ /* Allocate read_data block */ -+ msBlk->read_size = (sBlk->block_size < SQUASHFS_METADATA_SIZE) ? SQUASHFS_METADATA_SIZE : sBlk->block_size; -+ if(!(msBlk->read_data = (char *) kmalloc(msBlk->read_size, GFP_KERNEL))) { -+ ERROR("Failed to allocate read_data block\n"); -+ goto failed_mount1; -+ } -+ -+ /* Allocate read_page block */ -+ if(sBlk->block_size > PAGE_CACHE_SIZE && -+ !(msBlk->read_page = (char *) kmalloc(sBlk->block_size, GFP_KERNEL))) { -+ ERROR("Failed to allocate read_page block\n"); -+ goto failed_mount2; -+ } -+ -+ /* Allocate uid and gid tables */ -+ if(!(msBlk->uid = (squashfs_uid *) kmalloc((sBlk->no_uids + -+ sBlk->no_guids) * sizeof(squashfs_uid), GFP_KERNEL))) { -+ ERROR("Failed to allocate uid/gid table\n"); -+ goto failed_mount3; -+ } -+ msBlk->guid = msBlk->uid + sBlk->no_uids; -+ -+ if(msBlk->swap) { -+ squashfs_uid suid[sBlk->no_uids + sBlk->no_guids]; -+ -+ if(!read_data(s, (char *) &suid, sBlk->uid_start, ((sBlk->no_uids + sBlk->no_guids) * -+ sizeof(squashfs_uid)) | SQUASHFS_COMPRESSED_BIT, 0, NULL)) { -+ SERROR("unable to read uid/gid table\n"); -+ goto failed_mount4; -+ } -+ SQUASHFS_SWAP_DATA(msBlk->uid, suid, (sBlk->no_uids + sBlk->no_guids), (sizeof(squashfs_uid) * 8)); -+ } else -+ if(!read_data(s, (char *) msBlk->uid, sBlk->uid_start, ((sBlk->no_uids + sBlk->no_guids) * -+ sizeof(squashfs_uid)) | SQUASHFS_COMPRESSED_BIT, 0, NULL)) { -+ SERROR("unable to read uid/gid table\n"); -+ goto failed_mount4; -+ } -+ -+ -+#ifdef SQUASHFS_1_0_COMPATIBILITY -+ if(sBlk->s_major == 1) { -+ msBlk->iget = squashfs_iget_1; -+ msBlk->read_blocklist = read_blocklist_1; -+ msBlk->fragment = (struct squashfs_fragment_cache *) msBlk->fragment_index = NULL; -+ goto allocate_root; -+ } -+#endif -+ msBlk->iget = squashfs_iget; -+ msBlk->read_blocklist = read_blocklist; -+ -+ if(!(msBlk->fragment = (struct squashfs_fragment_cache *) kmalloc(sizeof(struct squashfs_fragment_cache) * SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) { -+ ERROR("Failed to allocate fragment block cache\n"); -+ goto failed_mount4; -+ } -+ -+ for(i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) { -+ msBlk->fragment[i].locked = 0; -+ msBlk->fragment[i].block = SQUASHFS_INVALID_BLK; -+ msBlk->fragment[i].data = NULL; -+ } -+ -+ msBlk->next_fragment = 0; -+ -+ /* Allocate fragment index table */ -+ if(!(msBlk->fragment_index = (squashfs_fragment_index *) kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES(sBlk->fragments), GFP_KERNEL))) { -+ ERROR("Failed to allocate uid/gid table\n"); -+ goto failed_mount5; -+ } -+ -+ if(SQUASHFS_FRAGMENT_INDEX_BYTES(sBlk->fragments) && -+ !read_data(s, (char *) msBlk->fragment_index, sBlk->fragment_table_start, -+ SQUASHFS_FRAGMENT_INDEX_BYTES(sBlk->fragments) | SQUASHFS_COMPRESSED_BIT, 0, NULL)) { -+ SERROR("unable to read fragment index table\n"); -+ goto failed_mount6; -+ } -+ -+ if(msBlk->swap) { -+ int i; -+ squashfs_fragment_index fragment; -+ -+ for(i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sBlk->fragments); i++) { -+ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment), &msBlk->fragment_index[i], 1); -+ msBlk->fragment_index[i] = fragment; -+ } -+ } -+ -+#ifdef SQUASHFS_1_0_COMPATIBILITY -+allocate_root: -+#endif -+ if(!(s->s_root = d_alloc_root((msBlk->iget)(s, sBlk->root_inode)))) { -+ ERROR("Root inode create failed\n"); -+ goto failed_mount5; -+ } -+ -+ TRACE("Leaving squashfs_read_super\n"); -+ return s; -+ -+failed_mount6: -+ kfree(msBlk->fragment_index); -+failed_mount5: -+ kfree(msBlk->fragment); -+failed_mount4: -+ kfree(msBlk->uid); -+failed_mount3: -+ kfree(msBlk->read_page); -+failed_mount2: -+ kfree(msBlk->read_data); -+failed_mount1: -+ kfree(msBlk->block_cache); -+failed_mount: -+ return NULL; -+} -+ -+ -+static int squashfs_statfs(struct super_block *s, struct statfs *buf) -+{ -+ squashfs_super_block *sBlk = &s->u.squashfs_sb.sBlk; -+ -+ TRACE("Entered squashfs_statfs\n"); -+ buf->f_type = SQUASHFS_MAGIC; -+ buf->f_bsize = sBlk->block_size; -+ buf->f_blocks = ((sBlk->bytes_used - 1) >> sBlk->block_log) + 1; -+ buf->f_bfree = buf->f_bavail = 0; -+ buf->f_files = sBlk->inodes; -+ buf->f_ffree = 0; -+ buf->f_namelen = SQUASHFS_NAME_LEN; -+ return 0; -+} -+ -+ -+static int squashfs_symlink_readpage(struct file *file, struct page *page) -+{ -+ struct inode *inode = page->mapping->host; -+ int index = page->index << PAGE_CACHE_SHIFT, length, bytes; -+ int block = inode->u.squashfs_i.start_block; -+ int offset = inode->u.squashfs_i.offset; -+ void *pageaddr = kmap(page); -+ -+ TRACE("Entered squashfs_symlink_readpage, page index %x, start block %x, offset %x\n", -+ (unsigned int) page->index, inode->u.squashfs_i.start_block, inode->u.squashfs_i.offset); -+ -+ for(length = 0; length < index; length += bytes) { -+ if(!(bytes = squashfs_get_cached_block(inode->i_sb, NULL, block, offset, -+ PAGE_CACHE_SIZE, &block, &offset))) { -+ ERROR("Unable to read symbolic link [%x:%x]\n", block, offset); -+ goto skip_read; -+ } -+ } -+ -+ if(length != index) { -+ ERROR("(squashfs_symlink_readpage) length != index\n"); -+ bytes = 0; -+ goto skip_read; -+ } -+ -+ bytes = (inode->i_size - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE : inode->i_size - length; -+ if(!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, offset, bytes, &block, &offset))) -+ ERROR("Unable to read symbolic link [%x:%x]\n", block, offset); -+ -+skip_read: -+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); -+ kunmap(page); -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ UnlockPage(page); -+ -+ return 0; -+} -+ -+ -+#define SIZE 256 -+ -+#ifdef SQUASHFS_1_0_COMPATIBILITY -+static unsigned int read_blocklist_1(struct inode *inode, int index, int readahead_blks, -+ char *block_list, char **block_p, unsigned int *bsize) -+{ -+ squashfs_sb_info *msBlk = &inode->i_sb->u.squashfs_sb; -+ unsigned short *block_listp; -+ int i = 0; -+ int block_ptr = inode->u.squashfs_i.block_list_start; -+ int offset = inode->u.squashfs_i.offset; -+ int block = inode->u.squashfs_i.start_block; -+ -+ for(;;) { -+ int blocks = (index + readahead_blks - i); -+ if(blocks > (SIZE >> 1)) { -+ if((index - i) <= (SIZE >> 1)) -+ blocks = index - i; -+ else -+ blocks = SIZE >> 1; -+ } -+ -+ if(msBlk->swap) { -+ unsigned char sblock_list[SIZE]; -+ if(!squashfs_get_cached_block(inode->i_sb, (char *) sblock_list, block_ptr, offset, blocks << 1, &block_ptr, &offset)) { -+ ERROR("Unable to read block list [%d:%x]\n", block_ptr, offset); -+ return 0; -+ } -+ SQUASHFS_SWAP_SHORTS(((unsigned short *)block_list), ((unsigned short *)sblock_list), blocks); -+ } else -+ if(!squashfs_get_cached_block(inode->i_sb, (char *) block_list, block_ptr, offset, blocks << 1, &block_ptr, &offset)) { -+ ERROR("Unable to read block list [%d:%x]\n", block_ptr, offset); -+ return 0; -+ } -+ for(block_listp = (unsigned short *) block_list; i < index && blocks; i ++, block_listp ++, blocks --) -+ block += SQUASHFS_COMPRESSED_SIZE(*block_listp); -+ if(blocks >= readahead_blks) -+ break; -+ } -+ -+ if(bsize) -+ *bsize = SQUASHFS_COMPRESSED_SIZE(*block_listp) | (!SQUASHFS_COMPRESSED(*block_listp) ? SQUASHFS_COMPRESSED_BIT_BLOCK : 0); -+ else -+ (unsigned short *) *block_p = block_listp; -+ return block; -+} -+#endif -+ -+ -+ -+static unsigned int read_blocklist(struct inode *inode, int index, int readahead_blks, -+ char *block_list, char **block_p, unsigned int *bsize) -+{ -+ squashfs_sb_info *msBlk = &inode->i_sb->u.squashfs_sb; -+ unsigned int *block_listp; -+ int i = 0; -+ int block_ptr = inode->u.squashfs_i.block_list_start; -+ int offset = inode->u.squashfs_i.offset; -+ int block = inode->u.squashfs_i.start_block; -+ -+ for(;;) { -+ int blocks = (index + readahead_blks - i); -+ if(blocks > (SIZE >> 2)) { -+ if((index - i) <= (SIZE >> 2)) -+ blocks = index - i; -+ else -+ blocks = SIZE >> 2; -+ } -+ -+ if(msBlk->swap) { -+ unsigned char sblock_list[SIZE]; -+ if(!squashfs_get_cached_block(inode->i_sb, (char *) sblock_list, block_ptr, offset, blocks << 2, &block_ptr, &offset)) { -+ ERROR("Unable to read block list [%d:%x]\n", block_ptr, offset); -+ return 0; -+ } -+ SQUASHFS_SWAP_INTS(((unsigned int *)block_list), ((unsigned int *)sblock_list), blocks); -+ } else -+ if(!squashfs_get_cached_block(inode->i_sb, (char *) block_list, block_ptr, offset, blocks << 2, &block_ptr, &offset)) { -+ ERROR("Unable to read block list [%d:%x]\n", block_ptr, offset); -+ return 0; -+ } -+ for(block_listp = (unsigned int *) block_list; i < index && blocks; i ++, block_listp ++, blocks --) -+ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp); -+ if(blocks >= readahead_blks) -+ break; -+ } -+ -+ *bsize = *block_listp; -+ return block; -+} -+ -+ -+static int squashfs_readpage(struct file *file, struct page *page) -+{ -+ struct inode *inode = page->mapping->host; -+ squashfs_sb_info *msBlk = &inode->i_sb->u.squashfs_sb; -+ squashfs_super_block *sBlk = &msBlk->sBlk; -+ unsigned char block_list[SIZE]; -+ unsigned int bsize, block, i = 0, bytes = 0, byte_offset = 0; -+ int index = page->index >> (sBlk->block_log - PAGE_CACHE_SHIFT); -+ void *pageaddr = kmap(page); -+ struct squashfs_fragment_cache *fragment; -+ char *data_ptr = msBlk->read_page; -+ -+ int mask = (1 << (sBlk->block_log - PAGE_CACHE_SHIFT)) - 1; -+ int start_index = page->index & ~mask; -+ int end_index = start_index | mask; -+ -+ TRACE("Entered squashfs_readpage, page index %x, start block %x\n", (unsigned int) page->index, -+ inode->u.squashfs_i.start_block); -+ -+ if(inode->u.squashfs_i.fragment_start_block == SQUASHFS_INVALID_BLK || index < (inode->i_size >> sBlk->block_log)) { -+ if((block = (msBlk->read_blocklist)(inode, index, 1, block_list, NULL, &bsize)) == 0) -+ goto skip_read; -+ -+ down(&msBlk->read_page_mutex); -+ if(!(bytes = read_data(inode->i_sb, msBlk->read_page, block, bsize, 1, NULL))) { -+ ERROR("Unable to read page, block %x, size %x\n", block, bsize); -+ up(&msBlk->read_page_mutex); -+ goto skip_read; -+ } -+ } else { -+ if((fragment = get_cached_fragment(inode->i_sb, inode->u.squashfs_i.fragment_start_block, inode->u.squashfs_i.fragment_size)) == NULL) { -+ ERROR("Unable to read page, block %x, size %x\n", inode->u.squashfs_i.fragment_start_block, (int) inode->u.squashfs_i.fragment_size); -+ goto skip_read; -+ } -+ bytes = inode->u.squashfs_i.fragment_offset + (inode->i_size & (sBlk->block_size - 1)); -+ byte_offset = inode->u.squashfs_i.fragment_offset; -+ data_ptr = fragment->data; -+ } -+ -+ for(i = start_index; i <= end_index && byte_offset < bytes; i++, byte_offset += PAGE_CACHE_SIZE) { -+ struct page *push_page; -+ int available_bytes = (bytes - byte_offset) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE : bytes - byte_offset; -+ -+ TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n", bytes, i, byte_offset, available_bytes); -+ -+ if(i == page->index) { -+ memcpy(pageaddr, data_ptr + byte_offset, available_bytes); -+ memset(pageaddr + available_bytes, 0, PAGE_CACHE_SIZE - available_bytes); -+ kunmap(page); -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ UnlockPage(page); -+ } else if((push_page = grab_cache_page_nowait(page->mapping, i))) { -+ void *pageaddr = kmap(push_page); -+ memcpy(pageaddr, data_ptr + byte_offset, available_bytes); -+ memset(pageaddr + available_bytes, 0, PAGE_CACHE_SIZE - available_bytes); -+ kunmap(push_page); -+ flush_dcache_page(push_page); -+ SetPageUptodate(push_page); -+ UnlockPage(push_page); -+ page_cache_release(push_page); -+ } -+ } -+ -+ if(inode->u.squashfs_i.fragment_start_block == SQUASHFS_INVALID_BLK || index < (inode->i_size >> sBlk->block_log)) -+ up(&msBlk->read_page_mutex); -+ else -+ release_cached_fragment(msBlk, fragment); -+ -+ return 0; -+ -+skip_read: -+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); -+ kunmap(page); -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ UnlockPage(page); -+ -+ return 0; -+} -+ -+ -+static int squashfs_readpage4K(struct file *file, struct page *page) -+{ -+ struct inode *inode = page->mapping->host; -+ squashfs_sb_info *msBlk = &inode->i_sb->u.squashfs_sb; -+ squashfs_super_block *sBlk = &msBlk->sBlk; -+ unsigned char block_list[SIZE]; -+ unsigned int bsize, block, bytes = 0; -+ void *pageaddr = kmap(page); -+ -+ TRACE("Entered squashfs_readpage4K, page index %x, start block %x\n", (unsigned int) page->index, -+ inode->u.squashfs_i.start_block); -+ -+ if(page->index < (inode->i_size >> sBlk->block_log)) { -+ block = (msBlk->read_blocklist)(inode, page->index, 1, block_list, NULL, &bsize); -+ -+ if(!(bytes = read_data(inode->i_sb, pageaddr, block, bsize, 1, NULL))) -+ ERROR("Unable to read page, block %x, size %x\n", block, bsize); -+ } else { -+ struct squashfs_fragment_cache *fragment; -+ -+ if((fragment = get_cached_fragment(inode->i_sb, inode->u.squashfs_i.fragment_start_block, inode->u.squashfs_i.fragment_size)) == NULL) -+ ERROR("Unable to read page, block %x, size %x\n", inode->u.squashfs_i.fragment_start_block, (int) inode->u.squashfs_i.fragment_size); -+ else { -+ bytes = inode->i_size & (sBlk->block_size - 1); -+ memcpy(pageaddr, fragment->data + inode->u.squashfs_i.fragment_offset, bytes); -+ release_cached_fragment(msBlk, fragment); -+ } -+ } -+ -+ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); -+ kunmap(page); -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ UnlockPage(page); -+ -+ return 0; -+} -+ -+ -+#ifdef SQUASHFS_1_0_COMPATIBILITY -+static int squashfs_readpage_lessthan4K(struct file *file, struct page *page) -+{ -+ struct inode *inode = page->mapping->host; -+ squashfs_sb_info *msBlk = &inode->i_sb->u.squashfs_sb; -+ squashfs_super_block *sBlk = &msBlk->sBlk; -+ unsigned char block_list[SIZE]; -+ unsigned short *block_listp, block, bytes = 0; -+ int index = page->index << (PAGE_CACHE_SHIFT - sBlk->block_log); -+ int file_blocks = ((inode->i_size - 1) >> sBlk->block_log) + 1; -+ int readahead_blks = 1 << (PAGE_CACHE_SHIFT - sBlk->block_log); -+ void *pageaddr = kmap(page); -+ -+ int i_end = index + (1 << (PAGE_CACHE_SHIFT - sBlk->block_log)); -+ int byte; -+ -+ TRACE("Entered squashfs_readpage_lessthan4K, page index %x, start block %x\n", (unsigned int) page->index, -+ inode->u.squashfs_i.start_block); -+ -+ block = read_blocklist_1(inode, index, readahead_blks, block_list, (char **) &block_listp, NULL); -+ -+ if(i_end > file_blocks) -+ i_end = file_blocks; -+ -+ while(index < i_end) { -+ if(!(byte = read_data(inode->i_sb, pageaddr, block, *block_listp, 0, NULL))) { -+ ERROR("Unable to read page, block %x, size %x\n", block, *block_listp); -+ goto skip_read; -+ } -+ block += SQUASHFS_COMPRESSED_SIZE(*block_listp); -+ pageaddr += byte; -+ bytes += byte; -+ index ++; -+ block_listp ++; -+ } -+ -+skip_read: -+ memset(pageaddr, 0, PAGE_CACHE_SIZE - bytes); -+ kunmap(page); -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ UnlockPage(page); -+ -+ return 0; -+} -+#endif -+ -+ -+static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) -+{ -+ struct inode *i = file->f_dentry->d_inode; -+ squashfs_sb_info *msBlk = &i->i_sb->u.squashfs_sb; -+ squashfs_super_block *sBlk = &msBlk->sBlk; -+ int next_block = i->u.squashfs_i.start_block + sBlk->directory_table_start, next_offset = -+ i->u.squashfs_i.offset, length = 0, dirs_read = 0, dir_count; -+ squashfs_dir_header dirh; -+ char buffer[sizeof(squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1]; -+ squashfs_dir_entry *dire = (squashfs_dir_entry *) buffer; -+ -+ TRACE("Entered squashfs_readdir [%x:%x]\n", next_block, next_offset); -+ -+ while(length < i->i_size) { -+ /* read directory header */ -+ if(msBlk->swap) { -+ squashfs_dir_header sdirh; -+ if(!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, next_block, -+ next_offset, sizeof(sdirh), &next_block, &next_offset)) -+ goto failed_read; -+ length += sizeof(sdirh); -+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); -+ } else { -+ if(!squashfs_get_cached_block(i->i_sb, (char *) &dirh, next_block, -+ next_offset, sizeof(dirh), &next_block, &next_offset)) -+ goto failed_read; -+ length += sizeof(dirh); -+ } -+ -+ dir_count = dirh.count + 1; -+ while(dir_count--) { -+ if(msBlk->swap) { -+ squashfs_dir_entry sdire; -+ if(!squashfs_get_cached_block(i->i_sb, (char *) &sdire, next_block, -+ next_offset, sizeof(sdire), &next_block, &next_offset)) -+ goto failed_read; -+ length += sizeof(sdire); -+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); -+ } else { -+ if(!squashfs_get_cached_block(i->i_sb, (char *) dire, next_block, -+ next_offset, sizeof(*dire), &next_block, &next_offset)) -+ goto failed_read; -+ length += sizeof(*dire); -+ } -+ -+ if(!squashfs_get_cached_block(i->i_sb, dire->name, next_block, -+ next_offset, dire->size + 1, &next_block, &next_offset)) -+ goto failed_read; -+ length += dire->size + 1; -+ -+ if(file->f_pos >= length) -+ continue; -+ -+ dire->name[dire->size + 1] = '\0'; -+ -+ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n", (unsigned int) dirent, -+ dire->name, dire->size + 1, (int) file->f_pos, -+ dirh.start_block, dire->offset, squashfs_filetype_table[dire->type]); -+ -+ if(filldir(dirent, dire->name, dire->size + 1, file->f_pos, SQUASHFS_MK_VFS_INODE(dirh.start_block, -+ dire->offset), squashfs_filetype_table[dire->type]) < 0) { -+ TRACE("Filldir returned less than 0\n"); -+ return dirs_read; -+ } -+ -+ file->f_pos = length; -+ dirs_read ++; -+ } -+ } -+ -+ return dirs_read; -+ -+failed_read: -+ ERROR("Unable to read directory block [%x:%x]\n", next_block, next_offset); -+ return 0; -+} -+ -+ -+static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry) -+{ -+ const char *name =dentry->d_name.name; -+ int len = dentry->d_name.len; -+ struct inode *inode = NULL; -+ squashfs_sb_info *msBlk = &i->i_sb->u.squashfs_sb; -+ squashfs_super_block *sBlk = &msBlk->sBlk; -+ int next_block = i->u.squashfs_i.start_block + sBlk->directory_table_start, next_offset = -+ i->u.squashfs_i.offset, length = 0, dir_count; -+ squashfs_dir_header dirh; -+ char buffer[sizeof(squashfs_dir_entry) + SQUASHFS_NAME_LEN]; -+ squashfs_dir_entry *dire = (squashfs_dir_entry *) buffer; -+ -+ TRACE("Entered squashfs_lookup [%x:%x]\n", next_block, next_offset); -+ -+ while(length < i->i_size) { -+ /* read directory header */ -+ if(msBlk->swap) { -+ squashfs_dir_header sdirh; -+ if(!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, next_block, next_offset, -+ sizeof(sdirh), &next_block, &next_offset)) -+ goto failed_read; -+ length += sizeof(sdirh); -+ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); -+ } else { -+ if(!squashfs_get_cached_block(i->i_sb, (char *) &dirh, next_block, next_offset, -+ sizeof(dirh), &next_block, &next_offset)) -+ goto failed_read; -+ length += sizeof(dirh); -+ } -+ -+ dir_count = dirh.count + 1; -+ while(dir_count--) { -+ if(msBlk->swap) { -+ squashfs_dir_entry sdire; -+ if(!squashfs_get_cached_block(i->i_sb, (char *) &sdire, -+ next_block,next_offset, sizeof(sdire), &next_block, &next_offset)) -+ goto failed_read; -+ length += sizeof(sdire); -+ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); -+ } else { -+ if(!squashfs_get_cached_block(i->i_sb, (char *) dire, -+ next_block,next_offset, sizeof(*dire), &next_block, &next_offset)) -+ goto failed_read; -+ length += sizeof(*dire); -+ } -+ -+ if(!squashfs_get_cached_block(i->i_sb, dire->name, -+ next_block, next_offset, dire->size + 1, &next_block, &next_offset)) -+ goto failed_read; -+ length += dire->size + 1; -+ -+ if((len == dire->size + 1) && !strncmp(name, dire->name, len)) { -+ squashfs_inode ino = SQUASHFS_MKINODE(dirh.start_block, dire->offset); -+ -+ TRACE("calling squashfs_iget for directory entry %s, inode %x:%x\n", -+ name, dirh.start_block, dire->offset); -+ -+ inode = (msBlk->iget)(i->i_sb, ino); -+ -+ goto exit_loop; -+ } -+ } -+ } -+ -+exit_loop: -+ d_add(dentry, inode); -+ return ERR_PTR(0); -+ -+failed_read: -+ ERROR("Unable to read directory block [%x:%x]\n", next_block, next_offset); -+ goto exit_loop; -+} -+ -+ -+static void squashfs_put_super(struct super_block *s) -+{ -+ if(s->u.squashfs_sb.block_cache) kfree(s->u.squashfs_sb.block_cache); -+ if(s->u.squashfs_sb.read_data) kfree(s->u.squashfs_sb.read_data); -+ if(s->u.squashfs_sb.read_page) kfree(s->u.squashfs_sb.read_page); -+ if(s->u.squashfs_sb.uid) kfree(s->u.squashfs_sb.uid); -+ s->u.squashfs_sb.block_cache = (void *) s->u.squashfs_sb.uid = -+ s->u.squashfs_sb.read_data = s->u.squashfs_sb.read_page = NULL; -+} -+ -+ -+static int __init init_squashfs_fs(void) -+{ -+ -+ if(!(stream.workspace = (char *) vmalloc(zlib_inflate_workspacesize()))) { -+ ERROR("Failed to allocate zlib workspace\n"); -+ return -ENOMEM; -+ } -+ return register_filesystem(&squashfs_fs_type); -+} -+ -+ -+static void __exit exit_squashfs_fs(void) -+{ -+ vfree(stream.workspace); -+ unregister_filesystem(&squashfs_fs_type); -+} -+ -+ -+EXPORT_NO_SYMBOLS; -+ -+module_init(init_squashfs_fs); -+module_exit(exit_squashfs_fs); -+MODULE_DESCRIPTION("squashfs, a compressed read-only filesystem"); -+MODULE_AUTHOR("Phillip Lougher "); -+MODULE_LICENSE("GPL"); -diff -Nurb src/linux/linux.orig/include/linux/fs.h src/linux/linux/include/linux/fs.h ---- src/linux/linux.orig/include/linux/fs.h 2003-07-04 04:12:25.000000000 -0400 -+++ src/linux/linux/include/linux/fs.h 2004-05-25 21:13:03.000000000 -0400 -@@ -313,6 +313,7 @@ - #include - #include - #include -+#include - - /* - * Attribute flags. These should be or-ed together to figure out what -@@ -503,6 +504,7 @@ - struct socket socket_i; - struct usbdev_inode_info usbdev_i; - struct jffs2_inode_info jffs2_i; -+ struct squashfs_inode_info squashfs_i; - void *generic_ip; - } u; - }; -@@ -697,6 +699,7 @@ - #include - #include - #include -+#include - - extern struct list_head super_blocks; - extern spinlock_t sb_lock; -@@ -755,6 +758,7 @@ - struct usbdev_sb_info usbdevfs_sb; - struct jffs2_sb_info jffs2_sb; - struct cramfs_sb_info cramfs_sb; -+ struct squashfs_sb_info squashfs_sb; - void *generic_sbp; - } u; - /* -diff -Nurb src/linux/linux.orig/include/linux/squashfs_fs.h src/linux/linux/include/linux/squashfs_fs.h ---- src/linux/linux.orig/include/linux/squashfs_fs.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/squashfs_fs.h 2004-05-25 21:13:03.000000000 -0400 -@@ -0,0 +1,474 @@ -+#ifndef SQUASHFS_FS -+#define SQUASHFS_FS -+/* -+ * Squashfs -+ * -+ * Copyright (c) 2002, 2003, 2004 Phillip Lougher -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs_fs.h -+ */ -+ -+#define SQUASHFS_MAJOR 2 -+#define SQUASHFS_MINOR 0 -+#define SQUASHFS_MAGIC 0x73717368 -+#define SQUASHFS_MAGIC_SWAP 0x68737173 -+#define SQUASHFS_START 0 -+ -+/* size of metadata (inode and directory) blocks */ -+#define SQUASHFS_METADATA_SIZE 8192 -+#define SQUASHFS_METADATA_LOG 13 -+ -+/* default size of data blocks */ -+#define SQUASHFS_FILE_SIZE 65536 -+#define SQUASHFS_FILE_LOG 16 -+ -+#define SQUASHFS_FILE_MAX_SIZE 65536 -+ -+/* Max number of uids and gids */ -+#define SQUASHFS_UIDS 256 -+#define SQUASHFS_GUIDS 255 -+ -+/* Max length of filename (not 255) */ -+#define SQUASHFS_NAME_LEN 256 -+ -+#define SQUASHFS_INVALID ((long long) 0xffffffffffff) -+#define SQUASHFS_INVALID_BLK ((long long) 0xffffffff) -+#define SQUASHFS_USED_BLK ((long long) 0xfffffffe) -+ -+/* Filesystem flags */ -+#define SQUASHFS_NOI 0 -+#define SQUASHFS_NOD 1 -+#define SQUASHFS_CHECK 2 -+#define SQUASHFS_NOF 3 -+#define SQUASHFS_NO_FRAG 4 -+#define SQUASHFS_ALWAYS_FRAG 5 -+#define SQUASHFS_DUPLICATE 6 -+#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) -+#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, SQUASHFS_NOI) -+#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, SQUASHFS_NOD) -+#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, SQUASHFS_NOF) -+#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, SQUASHFS_NO_FRAG) -+#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, SQUASHFS_ALWAYS_FRAG) -+#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, SQUASHFS_DUPLICATE) -+#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, SQUASHFS_CHECK) -+#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, duplicate_checking) (noi | (nod << 1) | (check_data << 2) | (nof << 3) | (no_frag << 4) | (always_frag << 5) | (duplicate_checking << 6)) -+ -+/* Max number of types and file types */ -+#define SQUASHFS_DIR_TYPE 1 -+#define SQUASHFS_FILE_TYPE 2 -+#define SQUASHFS_SYMLINK_TYPE 3 -+#define SQUASHFS_BLKDEV_TYPE 4 -+#define SQUASHFS_CHRDEV_TYPE 5 -+#define SQUASHFS_FIFO_TYPE 6 -+#define SQUASHFS_SOCKET_TYPE 7 -+ -+/* 1.0 filesystem type definitions */ -+#define SQUASHFS_TYPES 5 -+#define SQUASHFS_IPC_TYPE 0 -+ -+/* Flag whether block is compressed or uncompressed, bit is set if block is uncompressed */ -+#define SQUASHFS_COMPRESSED_BIT (1 << 15) -+#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \ -+ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT) -+ -+#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT)) -+ -+#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24) -+#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? \ -+ (B) & ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK) -+ -+#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) -+ -+/* -+ * Inode number ops. Inodes consist of a compressed block number, and an uncompressed -+ * offset within that block -+ */ -+#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16)) -+#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff)) -+#define SQUASHFS_MKINODE(A, B) ((squashfs_inode)(((squashfs_inode) (A) << 16)\ -+ + (B))) -+ -+/* Compute 32 bit VFS inode number from squashfs inode number */ -+#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + ((b) >> 2) + 1)) -+ -+/* Translate between VFS mode and squashfs mode */ -+#define SQUASHFS_MODE(a) ((a) & 0xfff) -+ -+/* fragment and fragment table defines */ -+typedef unsigned int squashfs_fragment_index; -+#define SQUASHFS_FRAGMENT_BYTES(A) (A * sizeof(squashfs_fragment_entry)) -+#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / SQUASHFS_METADATA_SIZE) -+#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % SQUASHFS_METADATA_SIZE) -+#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + SQUASHFS_METADATA_SIZE - 1) / SQUASHFS_METADATA_SIZE) -+#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) * sizeof(squashfs_fragment_index)) -+#define SQUASHFS_CACHED_FRAGMENTS 3 -+ -+/* cached data constants for filesystem */ -+#define SQUASHFS_CACHED_BLKS 8 -+ -+#define SQUASHFS_MAX_FILE_SIZE_LOG 32 -+#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << (SQUASHFS_MAX_FILE_SIZE_LOG - 1)) -+ -+#define SQUASHFS_MARKER_BYTE 0xff -+ -+/* -+ * definitions for structures on disk -+ */ -+ -+typedef unsigned int squashfs_block; -+typedef long long squashfs_inode; -+ -+typedef unsigned int squashfs_uid; -+ -+typedef struct squashfs_super_block { -+ unsigned int s_magic; -+ unsigned int inodes; -+ unsigned int bytes_used; -+ unsigned int uid_start; -+ unsigned int guid_start; -+ unsigned int inode_table_start; -+ unsigned int directory_table_start; -+ unsigned int s_major:16; -+ unsigned int s_minor:16; -+ unsigned int block_size_1:16; -+ unsigned int block_log:16; -+ unsigned int flags:8; -+ unsigned int no_uids:8; -+ unsigned int no_guids:8; -+ time_t mkfs_time /* time of filesystem creation */; -+ squashfs_inode root_inode; -+ unsigned int block_size; -+ unsigned int fragments; -+ unsigned int fragment_table_start; -+} __attribute__ ((packed)) squashfs_super_block; -+ -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+} __attribute__ ((packed)) squashfs_base_inode_header; -+ -+typedef squashfs_base_inode_header squashfs_ipc_inode_header; -+ -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned short rdev; -+} __attribute__ ((packed)) squashfs_dev_inode_header; -+ -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned short symlink_size; -+ char symlink[0]; -+} __attribute__ ((packed)) squashfs_symlink_inode_header; -+ -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ time_t mtime; -+ squashfs_block start_block; -+ unsigned int fragment; -+ unsigned int offset; -+ unsigned int file_size:SQUASHFS_MAX_FILE_SIZE_LOG; -+ unsigned short block_list[0]; -+} __attribute__ ((packed)) squashfs_reg_inode_header; -+ -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:8; /* index into uid table */ -+ unsigned int guid:8; /* index into guid table */ -+ unsigned int file_size:19; -+ unsigned int offset:13; -+ time_t mtime; -+ unsigned int start_block:24; -+} __attribute__ ((packed)) squashfs_dir_inode_header; -+ -+typedef union { -+ squashfs_base_inode_header base; -+ squashfs_dev_inode_header dev; -+ squashfs_symlink_inode_header symlink; -+ squashfs_reg_inode_header reg; -+ squashfs_dir_inode_header dir; -+ squashfs_ipc_inode_header ipc; -+} squashfs_inode_header; -+ -+typedef struct { -+ unsigned int offset:13; -+ unsigned int type:3; -+ unsigned int size:8; -+ char name[0]; -+} __attribute__ ((packed)) squashfs_dir_entry; -+ -+typedef struct { -+ unsigned int count:8; -+ unsigned int start_block:24; -+} __attribute__ ((packed)) squashfs_dir_header; -+ -+ -+typedef struct { -+ unsigned int start_block; -+ unsigned int size; -+} __attribute__ ((packed)) squashfs_fragment_entry; -+ -+extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen); -+extern int squashfs_uncompress_init(void); -+extern int squashfs_uncompress_exit(void); -+ -+/* -+ * macros to convert each packed bitfield structure from little endian to big -+ * endian and vice versa. These are needed when creating or using a filesystem on a -+ * machine with different byte ordering to the target architecture. -+ * -+ */ -+ -+#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\ -+ SQUASHFS_MEMSET(s, d, sizeof(squashfs_super_block));\ -+ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\ -+ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\ -+ SQUASHFS_SWAP((s)->bytes_used, d, 64, 32);\ -+ SQUASHFS_SWAP((s)->uid_start, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->guid_start, d, 128, 32);\ -+ SQUASHFS_SWAP((s)->inode_table_start, d, 160, 32);\ -+ SQUASHFS_SWAP((s)->directory_table_start, d, 192, 32);\ -+ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\ -+ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\ -+ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\ -+ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\ -+ SQUASHFS_SWAP((s)->flags, d, 288, 8);\ -+ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\ -+ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\ -+ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\ -+ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\ -+ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\ -+ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\ -+ SQUASHFS_SWAP((s)->fragment_table_start, d, 472, 32);\ -+} -+ -+#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\ -+ SQUASHFS_MEMSET(s, d, n);\ -+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ -+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ -+ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ -+ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ -+} -+ -+#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_ipc_inode_header)) -+ -+#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_dev_inode_header));\ -+ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\ -+} -+ -+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_symlink_inode_header));\ -+ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\ -+} -+ -+#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_reg_inode_header));\ -+ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\ -+ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\ -+ SQUASHFS_SWAP((s)->offset, d, 128, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 160, SQUASHFS_MAX_FILE_SIZE_LOG);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\ -+ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_dir_inode_header));\ -+ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\ -+ SQUASHFS_SWAP((s)->offset, d, 51, 13);\ -+ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\ -+ SQUASHFS_MEMSET(s, d, sizeof(squashfs_dir_header));\ -+ SQUASHFS_SWAP((s)->count, d, 0, 8);\ -+ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\ -+ SQUASHFS_MEMSET(s, d, sizeof(squashfs_dir_entry));\ -+ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ -+ SQUASHFS_SWAP((s)->type, d, 13, 3);\ -+ SQUASHFS_SWAP((s)->size, d, 16, 8);\ -+} -+ -+#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\ -+ SQUASHFS_MEMSET(s, d, sizeof(squashfs_fragment_entry));\ -+ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\ -+ SQUASHFS_SWAP((s)->size, d, 32, 32);\ -+} -+ -+#define SQUASHFS_SWAP_SHORTS(s, d, n) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_MEMSET(s, d, n * 2);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += 16)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\ -+} -+ -+#define SQUASHFS_SWAP_INTS(s, d, n) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_MEMSET(s, d, n * 4);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += 32)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\ -+} -+ -+#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\ -+ int entry;\ -+ int bit_position;\ -+ SQUASHFS_MEMSET(s, d, n * bits / 8);\ -+ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += bits)\ -+ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\ -+} -+ -+#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_INTS(s, d, n) -+ -+#ifdef SQUASHFS_1_0_COMPATIBILITY -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+} __attribute__ ((packed)) squashfs_base_inode_header_1; -+ -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned int type:4; -+ unsigned int offset:4; -+} __attribute__ ((packed)) squashfs_ipc_inode_header_1; -+ -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned short rdev; -+} __attribute__ ((packed)) squashfs_dev_inode_header_1; -+ -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned short symlink_size; -+ char symlink[0]; -+} __attribute__ ((packed)) squashfs_symlink_inode_header_1; -+ -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ time_t mtime; -+ squashfs_block start_block; -+ unsigned int file_size:SQUASHFS_MAX_FILE_SIZE_LOG; -+ unsigned short block_list[0]; -+} __attribute__ ((packed)) squashfs_reg_inode_header_1; -+ -+typedef struct { -+ unsigned int inode_type:4; -+ unsigned int mode:12; /* protection */ -+ unsigned int uid:4; /* index into uid table */ -+ unsigned int guid:4; /* index into guid table */ -+ unsigned int file_size:19; -+ unsigned int offset:13; -+ time_t mtime; -+ unsigned int start_block:24; -+} __attribute__ ((packed)) squashfs_dir_inode_header_1; -+ -+#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\ -+ SQUASHFS_MEMSET(s, d, n);\ -+ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ -+ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ -+ SQUASHFS_SWAP((s)->uid, d, 16, 4);\ -+ SQUASHFS_SWAP((s)->guid, d, 20, 4);\ -+} -+ -+#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, sizeof(squashfs_ipc_inode_header_1));\ -+ SQUASHFS_SWAP((s)->type, d, 24, 4);\ -+ SQUASHFS_SWAP((s)->offset, d, 28, 4);\ -+} -+ -+#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, sizeof(squashfs_dev_inode_header_1));\ -+ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\ -+} -+ -+#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_symlink_inode_header_1));\ -+ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\ -+} -+ -+#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_reg_inode_header_1));\ -+ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\ -+ SQUASHFS_SWAP((s)->file_size, d, 88, SQUASHFS_MAX_FILE_SIZE_LOG);\ -+} -+ -+#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\ -+ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_dir_inode_header_1));\ -+ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\ -+ SQUASHFS_SWAP((s)->offset, d, 43, 13);\ -+ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\ -+ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\ -+} -+#endif -+ -+#ifdef __KERNEL__ -+/* -+ * macros used to swap each structure entry, taking into account -+ * bitfields and different bitfield placing conventions on differing architectures -+ */ -+#include -+#ifdef __BIG_ENDIAN -+ /* convert from little endian to big endian */ -+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, tbits, b_pos) -+#else -+ /* convert from big endian to little endian */ -+#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, tbits, 64 - tbits - b_pos) -+#endif -+ -+#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ -+ int bits;\ -+ int b_pos = pos % 8;\ -+ unsigned long long val = 0;\ -+ unsigned char *s = (unsigned char *)p + (pos / 8);\ -+ unsigned char *d = ((unsigned char *) &val) + 7;\ -+ for(bits = 0; bits < (tbits + b_pos); bits += 8) \ -+ *d-- = *s++;\ -+ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ -+} -+#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n); -+#endif -+#endif -diff -Nurb src/linux/linux.orig/include/linux/squashfs_fs_i.h src/linux/linux/include/linux/squashfs_fs_i.h ---- src/linux/linux.orig/include/linux/squashfs_fs_i.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/squashfs_fs_i.h 2004-05-25 21:13:03.000000000 -0400 -@@ -0,0 +1,33 @@ -+#ifndef SQUASHFS_FS_I -+#define SQUASHFS_FS_I -+/* -+ * Squashfs -+ * -+ * Copyright (c) 2002, 2003, 2004 Phillip Lougher -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs_fs_i.h -+ */ -+ -+typedef struct squashfs_inode_info { -+ unsigned int start_block; -+ unsigned int block_list_start; -+ unsigned int offset; -+ unsigned int fragment_start_block; -+ unsigned int fragment_size; -+ unsigned int fragment_offset; -+ } squashfs_inode_info; -+#endif -diff -Nurb src/linux/linux.orig/include/linux/squashfs_fs_sb.h src/linux/linux/include/linux/squashfs_fs_sb.h ---- src/linux/linux.orig/include/linux/squashfs_fs_sb.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/linux/squashfs_fs_sb.h 2004-05-25 21:13:03.000000000 -0400 -@@ -0,0 +1,65 @@ -+#ifndef SQUASHFS_FS_SB -+#define SQUASHFS_FS_SB -+/* -+ * Squashfs -+ * -+ * Copyright (c) 2002, 2003, 2004 Phillip Lougher -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version 2, -+ * or (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ * -+ * squashfs_fs_sb.h -+ */ -+ -+#include -+ -+typedef struct { -+ unsigned int block; -+ int length; -+ unsigned int next_index; -+ char *data; -+ } squashfs_cache; -+ -+struct squashfs_fragment_cache { -+ unsigned int block; -+ int length; -+ unsigned int locked; -+ char *data; -+ }; -+ -+typedef struct squashfs_sb_info { -+ squashfs_super_block sBlk; -+ int devblksize; -+ int devblksize_log2; -+ int swap; -+ squashfs_cache *block_cache; -+ struct squashfs_fragment_cache *fragment; -+ int next_cache; -+ int next_fragment; -+ squashfs_uid *uid; -+ squashfs_uid *guid; -+ squashfs_fragment_index *fragment_index; -+ unsigned int read_size; -+ char *read_data; -+ char *read_page; -+ struct semaphore read_page_mutex; -+ struct semaphore block_cache_mutex; -+ struct semaphore fragment_mutex; -+ wait_queue_head_t waitq; -+ wait_queue_head_t fragment_wait_queue; -+ struct inode *(*iget)(struct super_block *s, squashfs_inode inode); -+ unsigned int (*read_blocklist)(struct inode *inode, int index, int readahead_blks, -+ char *block_list, char **block_p, unsigned int *bsize); -+ } squashfs_sb_info; -+#endif -diff -Nurb src/linux/linux.orig/init/do_mounts.c src/linux/linux/init/do_mounts.c ---- src/linux/linux.orig/init/do_mounts.c 2003-11-08 03:13:20.000000000 -0500 -+++ src/linux/linux/init/do_mounts.c 2004-05-25 21:13:03.000000000 -0400 -@@ -16,6 +16,7 @@ - #include - #include - #include -+#include - - #undef BUILD_CRAMDISK - -@@ -470,6 +471,7 @@ - * ext2 - * romfs - * gzip -+ * squashfs - */ - static int __init - identify_ramdisk_image(int fd, int start_block) -@@ -479,6 +481,7 @@ - struct ext2_super_block *ext2sb; - struct romfs_super_block *romfsb; - struct cramfs_super *cramfsb; -+ struct squashfs_super_block *squashfsb; - int nblocks = -1; - unsigned char *buf; - -@@ -490,6 +493,7 @@ - ext2sb = (struct ext2_super_block *) buf; - romfsb = (struct romfs_super_block *) buf; - cramfsb = (struct cramfs_super *) buf; -+ squashfsb = (struct squashfs_super_block *) buf; - memset(buf, 0xe5, size); - - /* -@@ -536,6 +540,15 @@ - goto done; - } - -+ /* squashfs is at block zero too */ -+ if (squashfsb->s_magic == SQUASHFS_MAGIC) { -+ printk(KERN_NOTICE -+ "RAMDISK: squashfs filesystem found at block %d\n", -+ start_block); -+ nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; -+ goto done; -+ } -+ - /* - * Read block 1 to test for minix and ext2 superblock - */ -diff -Nurb src/linux/linux.orig/kernel/ksyms.c src/linux/linux/kernel/ksyms.c ---- src/linux/linux.orig/kernel/ksyms.c 2003-07-04 04:12:28.000000000 -0400 -+++ src/linux/linux/kernel/ksyms.c 2004-05-25 21:12:24.000000000 -0400 -@@ -482,9 +482,9 @@ - EXPORT_SYMBOL(simple_strtoull); - EXPORT_SYMBOL(system_utsname); /* UTS data */ - EXPORT_SYMBOL(uts_sem); /* UTS semaphore */ --#ifndef __mips__ -+//#ifndef __mips__ //bite me. -mbm. - EXPORT_SYMBOL(sys_call_table); --#endif -+//#endif - EXPORT_SYMBOL(machine_restart); - EXPORT_SYMBOL(machine_halt); - EXPORT_SYMBOL(machine_power_off); -diff -Nurb src/linux/linux.orig/lib/Config.in src/linux/linux/lib/Config.in ---- src/linux/linux.orig/lib/Config.in 2003-07-04 04:12:29.000000000 -0400 -+++ src/linux/linux/lib/Config.in 2004-05-25 21:13:03.000000000 -0400 -@@ -8,12 +8,14 @@ - # Do we need the compression support? - # - if [ "$CONFIG_CRAMFS" = "y" -o \ -+ "$CONFIG_SQUASHFS" = "y" -o \ - "$CONFIG_PPP_DEFLATE" = "y" -o \ - "$CONFIG_JFFS2_FS" = "y" -o \ - "$CONFIG_ZISOFS_FS" = "y" ]; then - define_tristate CONFIG_ZLIB_INFLATE y - else - if [ "$CONFIG_CRAMFS" = "m" -o \ -+ "$CONFIG_SQUASHFS" = "m" -o \ - "$CONFIG_PPP_DEFLATE" = "m" -o \ - "$CONFIG_JFFS2_FS" = "m" -o \ - "$CONFIG_ZISOFS_FS" = "m" ]; then diff --git a/obsolete-buildroot/sources/openwrt-wrt54g-nfsswap.patch b/obsolete-buildroot/sources/openwrt-wrt54g-nfsswap.patch deleted file mode 100644 index bf848c129a..0000000000 --- a/obsolete-buildroot/sources/openwrt-wrt54g-nfsswap.patch +++ /dev/null @@ -1,2362 +0,0 @@ -diff -Nurb src/linux/linux.orig/Documentation/netswap.txt src/linux/linux/Documentation/netswap.txt ---- src/linux/linux.orig/Documentation/netswap.txt 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/Documentation/netswap.txt 2004-05-31 02:18:03.000000000 -0400 -@@ -0,0 +1,51 @@ -+ Swapping over network -+ -+Support for this is enabled via the CONFIG_NETSWAP option, which is -+automatically enabled when enabling swap files located on NFS volumes -+(CONFIG_SWAP_VIA_NFS). -+ -+When swapping to files located on a network file system like NFS or -+CODA or others or to nbd (network block device, see `nbd.txt') -+partitions there is the problem that this requires additional memory, -+besides the page which is currently swapped in or out, probably at -+least two more pages for each page in question. -+ -+This means that not only there needs to be free space left in the swap -+file or the swap partition, but in addition there must be enough free -+memory left in the system to perform the swap out of pages. -+ -+This is particularly painful as receiving data over the network itself -+consumes memory, and this memory is allocated from an interrupt -+context (i.e. in the interrupt handler of the network card). That -+means that on a congested network there are chances that the machine -+runs out of memory, simply because the network device's interrupt -+routines allocate memory faster that it is freed by swapping via -+network. -+ -+To cope with this problem, there is a new socket option `SO_SWAPPING' -+which has to be set on the `SOL_SOCKET' level with setsockopt() (see -+setsockopt(2)). When this option is set on any network socket, then -+the system will start to drop network packets it receives on any other -+socket when the number of free pages falls below a certain threshold. -+ -+This threshold initially is 4 pages less than `freepages.min' (see -+`Documentation/sysctl/vm.txt') but can be tuned using the sysctl -+interface by writing to the file `/proc/sys/net/swapping/threshold' -+ -+There are two other files: -+ -+`/proc/sys/net/swapping/dropped': -+ how many network packets have been dropped so far. This file is -+ writable, writing to it simply sets the counter to the given value -+ (useful for resetting the counter). -+ -+`/proc/sys/net/swapping/sock_count': -+ How many network sockets have the `SO_SWAPPING' option set (read -+ only, of course). -+ -+When using swap-files on NFS volumes, then the `SO_SWAPPING' option is -+set or cleared by swapon/swapoff system calls, so the user need not -+care about it. -+ -+Swapping over the network is insecure unless the data would be -+encrypted, which is not the case with NFS. It is also very slow. -diff -Nurb src/linux/linux.orig/Documentation/nfsswap.txt src/linux/linux/Documentation/nfsswap.txt ---- src/linux/linux.orig/Documentation/nfsswap.txt 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/Documentation/nfsswap.txt 2004-05-31 02:18:03.000000000 -0400 -@@ -0,0 +1,41 @@ -+ Swapping to files on NFS volumes -+ -+To do this you have to say `Y' or `M' to the CONFIG_SWAP_VIA_NFS -+configuration option. When compling support for this as a module you -+should read `Documentation/modules.txt'. For auto-loading of the -+module during the `swapon' system call you have to place a line like -+ -+alias swapfile-mod nfsswap -+ -+in `/etc/modules.conf' (or `/etc/conf.modules', depending on your -+setup). NFS volumes holding swapfile should be mounted with `rsize' -+and `wsize' set to something less than the size of a page, otherwise -+deadlocks caused by memory fragmentation can happen, i.e. mount the -+volume which is to hold the swapfiles with -+ -+mount -t nfs -o rsize=2048,wsize=2048 NFS_SERVER_IP:/server_volume /mount_point -+ -+or set the option in `/etc/fstab'. Read `Documentation/nfsroot.txt' to -+learn how to set mount options for the root file system, if your swap -+files are to be located on the root file system. -+ -+Setting the `rsize' and `wsize' to anything less than PAGE_SIZE is a -+performance hit, so you probably want to have at least two volumes -+mounted, one for the swapfiles, one for the rest. -+ -+You may want to read `Documentation/netswap.txt' as well. -+ -+Swapfiles on NFS volumes can be treated like any other swapfile, -+i.e. -+ -+dd if=/dev/zero of=/swapfiles/SWAPFILE bs=1k count=20480 -+mkswap /swapfiles/SWAPFILE -+swapon /swapfiles/SWAPFILE -+ -+will create a 20M swapfile and tell the system to use it. Actually, -+one could use lseek(2) to create an empty swapfile. This is different -+from swapfiles located on local harddisk. -+ -+Swapping over the network is insecure unless the data would be -+encrypted, which is not the case with NFS. It is also very slow. -+ -diff -Nurb src/linux/linux.orig/drivers/block/blkpg.c src/linux/linux/drivers/block/blkpg.c ---- src/linux/linux.orig/drivers/block/blkpg.c 2003-07-04 04:11:31.000000000 -0400 -+++ src/linux/linux/drivers/block/blkpg.c 2004-05-31 02:18:03.000000000 -0400 -@@ -34,7 +34,7 @@ - #include /* for set_device_ro() */ - #include - #include --#include /* for is_swap_partition() */ -+#include /* for swap_run_test() */ - #include /* for EXPORT_SYMBOL */ - - #include -@@ -114,6 +114,29 @@ - return 0; - } - -+/* swap_run_test() applies this hook to all swapfiles until it returns -+ * "1". If it never returns "1", the result of swap_run_test() is "0", -+ * otherwise "1". -+ */ -+static int is_swap_partition_hook(unsigned int flags, struct file *swap_file, -+ void *testdata) -+{ -+ kdev_t swap_dev = S_ISBLK(swap_file->f_dentry->d_inode->i_mode) -+ ? swap_file->f_dentry->d_inode->i_rdev : 0; -+ kdev_t dev = *((kdev_t *)testdata); -+ -+ if (flags & SWP_USED && dev == swap_dev) { -+ return 1; -+ } else { -+ return 0; -+ } -+} -+ -+static inline int is_swap_partition(kdev_t dev) -+{ -+ return swap_run_test(is_swap_partition_hook, &dev); -+} -+ - /* - * Delete a partition given by partition number - * -diff -Nurb src/linux/linux.orig/fs/Config.in src/linux/linux/fs/Config.in ---- src/linux/linux.orig/fs/Config.in 2004-05-31 02:02:43.000000000 -0400 -+++ src/linux/linux/fs/Config.in 2004-05-31 02:18:03.000000000 -0400 -@@ -4,6 +4,12 @@ - mainmenu_option next_comment - comment 'File systems' - -+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -+ tristate 'Swapping to block devices' CONFIG_BLKDEV_SWAP -+else -+ define_bool CONFIG_BLKDEV_SWAP y -+fi -+ - bool 'Quota support' CONFIG_QUOTA - tristate 'Kernel automounter support' CONFIG_AUTOFS_FS - tristate 'Kernel automounter version 4 support (also supports v3)' CONFIG_AUTOFS4_FS -@@ -110,6 +116,12 @@ - dep_tristate 'NFS file system support' CONFIG_NFS_FS $CONFIG_INET - dep_mbool ' Provide NFSv3 client support' CONFIG_NFS_V3 $CONFIG_NFS_FS - dep_bool ' Root file system on NFS' CONFIG_ROOT_NFS $CONFIG_NFS_FS $CONFIG_IP_PNP -+ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -+ dep_tristate ' Swapping via NFS (EXPERIMENTAL)' CONFIG_SWAP_VIA_NFS $CONFIG_NFS_FS -+ if [ "$CONFIG_SWAP_VIA_NFS" = "y" -o "$CONFIG_SWAP_VIA_NFS" = "m" ]; then -+ define_bool CONFIG_NETSWAP y -+ fi -+ fi - - dep_tristate 'NFS server support' CONFIG_NFSD $CONFIG_INET - dep_mbool ' Provide NFSv3 server support' CONFIG_NFSD_V3 $CONFIG_NFSD -diff -Nurb src/linux/linux.orig/fs/Makefile src/linux/linux/fs/Makefile ---- src/linux/linux.orig/fs/Makefile 2004-05-31 02:02:42.000000000 -0400 -+++ src/linux/linux/fs/Makefile 2004-05-31 02:18:03.000000000 -0400 -@@ -8,7 +8,7 @@ - O_TARGET := fs.o - - export-objs := filesystems.o open.o dcache.o buffer.o --mod-subdirs := nls -+mod-subdirs := nls nfs - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ - super.o block_dev.o char_dev.o stat.o exec.o pipe.o namei.o \ -@@ -70,6 +70,7 @@ - subdir-$(CONFIG_JFS_FS) += jfs - subdir-$(CONFIG_SQUASHFS) += squashfs - -+obj-$(CONFIG_BLKDEV_SWAP) += blkdev_swap.o - - obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o - obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o -diff -Nurb src/linux/linux.orig/fs/blkdev_swap.c src/linux/linux/fs/blkdev_swap.c ---- src/linux/linux.orig/fs/blkdev_swap.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/fs/blkdev_swap.c 2004-05-31 02:18:03.000000000 -0400 -@@ -0,0 +1,309 @@ -+/* -+ * Swapping to partitions or files located on partitions. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef DEBUG_BLKDEV_SWAP -+# define dprintk(fmt...) printk(##fmt) -+#else -+# define dprintk(fmt...) do { /* */ } while (0) -+#endif -+ -+#define BLKDEV_SWAP_ID "blkdev" -+#define BLKDEV_FILE_SWAP_ID "blkdev file" -+ -+/* -+ * Helper function, copied here from buffer.c -+ */ -+ -+/* -+ * Start I/O on a page. -+ * This function expects the page to be locked and may return -+ * before I/O is complete. You then have to check page->locked -+ * and page->uptodate. -+ * -+ * brw_page() is SMP-safe, although it's being called with the -+ * kernel lock held - but the code is ready. -+ * -+ * FIXME: we need a swapper_inode->get_block function to remove -+ * some of the bmap kludges and interface ugliness here. -+ */ -+int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size) -+{ -+ struct buffer_head *head, *bh; -+ -+ if (!PageLocked(page)) -+ panic("brw_page: page not locked for I/O"); -+ -+ if (!page->buffers) -+ create_empty_buffers(page, dev, size); -+ head = bh = page->buffers; -+ -+ /* Stage 1: lock all the buffers */ -+ do { -+ lock_buffer(bh); -+ bh->b_blocknr = *(b++); -+ set_bit(BH_Mapped, &bh->b_state); -+ set_buffer_async_io(bh); -+ bh = bh->b_this_page; -+ } while (bh != head); -+ -+ /* Stage 2: start the IO */ -+ do { -+ struct buffer_head *next = bh->b_this_page; -+ submit_bh(rw, bh); -+ bh = next; -+ } while (bh != head); -+ return 0; -+} -+ -+/* -+ * We implement to methods: swapping to partitions, and swapping to files -+ * located on partitions. -+ */ -+ -+struct blkdev_swap_data { -+ kdev_t dev; -+}; -+ -+struct test_data { -+ struct file * filp; -+ kdev_t dev; -+}; -+ -+static int is_blkdev_swapping(unsigned int flags, -+ struct file * swapf, -+ void *data) -+{ -+ struct test_data *testdata = (struct test_data *) data; -+ struct file * filp = testdata->filp; -+ kdev_t dev = testdata->dev; -+ -+ /* Only check filp's that don't match the one already opened -+ * for us by sys_swapon(). Otherwise, we will always flag a -+ * busy swap file. -+ */ -+ -+ if (swapf != filp) { -+ if (dev == swapf->f_dentry->d_inode->i_rdev) -+ return 1; -+ } -+ return 0; -+} -+ -+static int blkdev_swap_open(struct file * filp, void **dptr) -+{ -+ int swapfilesize; -+ kdev_t dev; -+ struct blkdev_swap_data *data; -+ int error; -+ struct test_data testdata; -+ -+ MOD_INC_USE_COUNT; -+ -+ if (!S_ISBLK(filp->f_dentry->d_inode->i_mode)) { -+ dprintk(__FUNCTION__": can't handle this swap file: %s\n", -+ swapf->d_name.name); -+ error = 0; /* not for us */ -+ goto bad_swap; -+ } -+ -+ dev = filp->f_dentry->d_inode->i_rdev; -+ set_blocksize(dev, PAGE_SIZE); -+ error = -ENODEV; -+ if (!dev || -+ (blk_size[MAJOR(dev)] && !blk_size[MAJOR(dev)][MINOR(dev)])) { -+ printk("blkdev_swap_open: blkdev weirdness for %s\n", -+ filp->f_dentry->d_name.name); -+ goto bad_swap; -+ } -+ -+ /* Check to make sure that we aren't already swapping. */ -+ error = -EBUSY; -+ testdata.filp = filp; -+ testdata.dev = dev; -+ if (swap_run_test(is_blkdev_swapping, &testdata)) { -+ printk("blkdev_swap_open: already swapping to %s\n", -+ filp->f_dentry->d_name.name); -+ goto bad_swap; -+ } -+ -+ swapfilesize = 0; -+ if (blk_size[MAJOR(dev)]) -+ swapfilesize = blk_size[MAJOR(dev)][MINOR(dev)] -+ >> (PAGE_SHIFT - 10); -+ -+ if ((data = kmalloc(sizeof(*data), GFP_KERNEL)) == NULL) { -+ printk("blkdev_swap_open: can't allocate data for %s\n", -+ filp->f_dentry->d_name.name); -+ error = -ENOMEM; -+ goto bad_swap; -+ } -+ data->dev = dev; -+ *dptr = data; -+ -+ dprintk("blkdev_swap_open: returning %d\n", swapfilesize); -+ return swapfilesize; -+ -+ bad_swap: -+ MOD_DEC_USE_COUNT; -+ return error; /* this swap thing is not for us */ -+} -+ -+static int blkdev_swap_release(struct file * filp, void *data) -+{ -+ dprintk("blkdev_swap_release: releasing swap device %s\n", -+ filp->f_dentry->d_name.name); -+ kfree(data); -+ MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+static int blkdev_rw_page(int rw, struct page *page, unsigned long offset, -+ void *ptr) -+{ -+ struct blkdev_swap_data *data = (struct blkdev_swap_data *)ptr; -+ brw_page(rw, page, data->dev, (int *)&offset, PAGE_SIZE); -+ return 1; -+} -+ -+static struct swap_ops blkdev_swap_ops = { -+ blkdev_swap_open, -+ blkdev_swap_release, -+ blkdev_rw_page -+}; -+ -+struct blkdevfile_swap_data { -+ struct inode *swapf; -+}; -+ -+static int is_blkdevfile_swapping(unsigned int flags, -+ struct file * swapf, -+ void * data) -+{ -+ struct file * filp = (struct file *) data; -+ -+ /* Only check filp's that don't match the one already opened -+ * for us by sys_swapon(). Otherwise, we will always flag a -+ * busy swap file. -+ */ -+ -+ if (swapf != filp) { -+ if (filp->f_dentry->d_inode == swapf->f_dentry->d_inode) -+ return 1; -+ } -+ return 0; -+} -+ -+static int blkdevfile_swap_open(struct file *swapf, void **dptr) -+{ -+ int error = 0; -+ int swapfilesize; -+ struct blkdevfile_swap_data *data; -+ -+ MOD_INC_USE_COUNT; -+ -+ /* first check whether this is a regular file located on a local -+ * hard disk -+ */ -+ if (!S_ISREG(swapf->f_dentry->d_inode->i_mode)) { -+ dprintk("blkdevfile_swap_open: " -+ "can't handle this swap file: %s\n", -+ swapf->d_name.name); -+ error = 0; /* not for us */ -+ goto bad_swap; -+ } -+ if (!swapf->f_dentry->d_inode->i_mapping->a_ops->bmap) { -+ dprintk("blkdevfile_swap_open: no bmap for file: %s\n", -+ swapf->d_name.name); -+ error = 0; /* not for us */ -+ goto bad_swap; -+ } -+ -+ if (swap_run_test(is_blkdevfile_swapping, swapf)) { -+ dprintk("blkdevfile_swap_open: already swapping to %s\n", -+ swapf->d_name.name); -+ error = -EBUSY; -+ goto bad_swap; -+ } -+ swapfilesize = swapf->f_dentry->d_inode->i_size >> PAGE_SHIFT; -+ if ((data = kmalloc(sizeof(*data), GFP_KERNEL)) == NULL) { -+ error = -ENOMEM; -+ goto bad_swap; -+ } -+ data->swapf = swapf->f_dentry->d_inode; -+ *dptr = data; -+ return swapfilesize; -+ -+ bad_swap: -+ MOD_DEC_USE_COUNT; -+ return error; -+} -+ -+static int blkdevfile_swap_release(struct file *swapf, void *data) -+{ -+ kfree(data); -+ MOD_DEC_USE_COUNT; -+ return 0; -+} -+ -+static int blkdevfile_rw_page(int rw, struct page *page, unsigned long offset, -+ void *ptr) -+{ -+ struct blkdevfile_swap_data *data = (struct blkdevfile_swap_data *)ptr; -+ struct inode * swapf = data->swapf; -+ int i, j; -+ unsigned int block = offset -+ << (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits); -+ kdev_t dev = swapf->i_dev; -+ int block_size; -+ int zones[PAGE_SIZE/512]; -+ int zones_used; -+ -+ block_size = swapf->i_sb->s_blocksize; -+ for (i=0, j=0; j< PAGE_SIZE ; i++, j += block_size) -+ if (!(zones[i] = bmap(swapf,block++))) { -+ printk("blkdevfile_rw_page: bad swap file\n"); -+ return 0; -+ } -+ zones_used = i; -+ -+ /* block_size == PAGE_SIZE/zones_used */ -+ brw_page(rw, page, dev, zones, block_size); -+ return 1; -+} -+ -+static struct swap_ops blkdevfile_swap_ops = { -+ blkdevfile_swap_open, -+ blkdevfile_swap_release, -+ blkdevfile_rw_page -+ }; -+ -+int __init blkdev_swap_init(void) -+{ -+ (void)register_swap_method(BLKDEV_SWAP_ID, &blkdev_swap_ops); -+ (void)register_swap_method(BLKDEV_FILE_SWAP_ID, &blkdevfile_swap_ops); -+ return 0; -+} -+ -+void __exit blkdev_swap_exit(void) -+{ -+ unregister_swap_method(BLKDEV_SWAP_ID); -+ unregister_swap_method(BLKDEV_FILE_SWAP_ID); -+} -+ -+module_init(blkdev_swap_init) -+module_exit(blkdev_swap_exit) -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Many. Stuffed into a module by cH (Claus-Justus Heine)"); -+MODULE_DESCRIPTION("Swapping to partitions and files on local hard-disks"); -diff -Nurb src/linux/linux.orig/fs/buffer.c src/linux/linux/fs/buffer.c ---- src/linux/linux.orig/fs/buffer.c 2003-07-04 04:12:05.000000000 -0400 -+++ src/linux/linux/fs/buffer.c 2004-05-31 02:21:05.000000000 -0400 -@@ -743,7 +743,7 @@ - bh->b_private = private; - } - --static void end_buffer_io_async(struct buffer_head * bh, int uptodate) -+void end_buffer_io_async(struct buffer_head * bh, int uptodate) - { - static spinlock_t page_uptodate_lock = SPIN_LOCK_UNLOCKED; - unsigned long flags; -@@ -2344,35 +2344,6 @@ - return err; - } - --int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size) --{ -- struct buffer_head *head, *bh; -- -- if (!PageLocked(page)) -- panic("brw_page: page not locked for I/O"); -- -- if (!page->buffers) -- create_empty_buffers(page, dev, size); -- head = bh = page->buffers; -- -- /* Stage 1: lock all the buffers */ -- do { -- lock_buffer(bh); -- bh->b_blocknr = *(b++); -- set_bit(BH_Mapped, &bh->b_state); -- set_buffer_async_io(bh); -- bh = bh->b_this_page; -- } while (bh != head); -- -- /* Stage 2: start the IO */ -- do { -- struct buffer_head *next = bh->b_this_page; -- submit_bh(rw, bh); -- bh = next; -- } while (bh != head); -- return 0; --} -- - int block_symlink(struct inode *inode, const char *symname, int len) - { - struct address_space *mapping = inode->i_mapping; -diff -Nurb src/linux/linux.orig/fs/nfs/Makefile src/linux/linux/fs/nfs/Makefile ---- src/linux/linux.orig/fs/nfs/Makefile 2003-07-04 04:12:07.000000000 -0400 -+++ src/linux/linux/fs/nfs/Makefile 2004-05-31 02:18:03.000000000 -0400 -@@ -15,6 +15,14 @@ - obj-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o - obj-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o - --obj-m := $(O_TARGET) -+obj-$(CONFIG_SWAP_VIA_NFS) += nfsswap.o -+ifeq ($(CONFIG_SWAP_VIA_NFS),m) -+export-objs := nfs_syms.o -+obj-y += nfs_syms.o -+endif -+ -+ifeq ($(CONFIG_NFS_FS),m) -+obj-m += $(O_TARGET) -+endif - - include $(TOPDIR)/Rules.make -diff -Nurb src/linux/linux.orig/fs/nfs/file.c src/linux/linux/fs/nfs/file.c ---- src/linux/linux.orig/fs/nfs/file.c 2003-07-04 04:12:07.000000000 -0400 -+++ src/linux/linux/fs/nfs/file.c 2004-05-31 02:18:03.000000000 -0400 -@@ -58,11 +58,6 @@ - setattr: nfs_notify_change, - }; - --/* Hack for future NFS swap support */ --#ifndef IS_SWAPFILE --# define IS_SWAPFILE(inode) (0) --#endif -- - /* - * Flush all dirty pages, and check for write errors. - * -@@ -217,8 +212,6 @@ - inode->i_ino, (unsigned long) count, (unsigned long) *ppos); - - result = -EBUSY; -- if (IS_SWAPFILE(inode)) -- goto out_swapfile; - result = nfs_revalidate_inode(NFS_SERVER(inode), inode); - if (result) - goto out; -@@ -230,10 +223,6 @@ - result = generic_file_write(file, buf, count, ppos); - out: - return result; -- --out_swapfile: -- printk(KERN_INFO "NFS: attempt to write to active swap file!\n"); -- goto out; - } - - /* -diff -Nurb src/linux/linux.orig/fs/nfs/nfs_syms.c src/linux/linux/fs/nfs/nfs_syms.c ---- src/linux/linux.orig/fs/nfs/nfs_syms.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/fs/nfs/nfs_syms.c 2004-05-31 02:18:03.000000000 -0400 -@@ -0,0 +1,10 @@ -+#include -+#define __NO_VERSION__ -+#include -+#include -+#include -+#include -+ -+EXPORT_SYMBOL(__nfs_refresh_inode); -+EXPORT_SYMBOL(nfs_write_attributes); -+ -diff -Nurb src/linux/linux.orig/fs/nfs/nfsswap.c src/linux/linux/fs/nfs/nfsswap.c ---- src/linux/linux.orig/fs/nfs/nfsswap.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/fs/nfs/nfsswap.c 2004-05-31 02:18:03.000000000 -0400 -@@ -0,0 +1,350 @@ -+/* -+ * Swapping to files located on NFS mounted volumes -+ * Copyright (c) 2000 Claus-Justus Heine -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define NFSDBG_FACILITY NFSDBG_SWAP -+ -+#define NFS_SWAP_ID "nfs file" -+ -+/* we cache some values here. In principle, we only need the file. -+ */ -+struct nfs_swap_data { -+ struct file *file; -+ struct inode *inode; -+ struct nfs_server *server; -+ struct socket *socket; -+}; -+ -+/* Nearly a clone of nfs_readpage_sync() in read.c, but "struct page" does not -+ * contain information about the file offset when swapping. So. -+ */ -+static int nfs_read_swap_page(struct page *page, -+ struct nfs_server *server, -+ struct inode *inode, -+ struct file *file) -+{ -+ unsigned int rsize = server->rsize; -+ unsigned int count = PAGE_SIZE; -+ unsigned int offset = 0; /* always at start of page */ -+ int result, eof; -+ struct rpc_cred *cred; -+ struct nfs_fattr fattr; -+ -+ cred = nfs_file_cred(file); -+ -+ do { -+ if (count < rsize) -+ rsize = count; -+ -+ lock_kernel(); -+ result = NFS_PROTO(inode)->read(inode, cred, -+ &fattr, -+ NFS_RPC_SWAPFLAGS, -+ offset, rsize, page, &eof); -+ nfs_refresh_inode(inode, &fattr); -+ unlock_kernel(); -+ -+ /* -+ * Even if we had a partial success we can't mark the page -+ * cache valid. -+ */ -+ if (result < 0) { -+ if (result == -EISDIR) -+ result = -EINVAL; -+ goto io_error; -+ } -+ count -= result; -+ offset += result; -+ if (result < rsize) /* NFSv2ism */ -+ break; -+ } while (count); -+ -+ if (count) { -+ char *kaddr = kmap(page); -+ memset(kaddr + offset, 0, count); -+ kunmap(page); -+ } -+ flush_dcache_page(page); -+ result = 0; -+ -+io_error: -+ return result; -+} -+ -+/* Like nfs_writepage_sync(), but when swapping page->index does not encode -+ * the offset in the swap file alone. -+ * -+ */ -+static int nfs_write_swap_page(struct page *page, -+ struct nfs_server *server, -+ struct inode *inode, -+ struct file *file) -+{ -+ struct rpc_cred *cred; -+ unsigned int wsize = server->wsize; -+ unsigned int count = PAGE_SIZE; -+ unsigned int offset = 0; -+ int result; -+ struct nfs_writeverf verf; -+ struct nfs_fattr fattr; -+ -+ cred = nfs_file_cred(file); -+ -+ do { -+ if (count < wsize) -+ wsize = count; -+ -+ lock_kernel(); -+ result = NFS_PROTO(inode)->write(inode, cred, &fattr, -+ NFS_RW_SWAP|NFS_RW_SYNC, -+ offset, wsize, page, &verf); -+ nfs_write_attributes(inode, &fattr); -+ unlock_kernel(); -+ -+ if (result < 0) { -+ goto io_error; -+ } -+ if (result != wsize) -+ printk("NFS: short write, wsize=%u, result=%d\n", -+ wsize, result); -+ offset += wsize; -+ count -= wsize; -+ /* -+ * If we've extended the file, update the inode -+ * now so we don't invalidate the cache. -+ */ -+ if (offset > inode->i_size) -+ inode->i_size = offset; -+ } while (count); -+ -+ result = 0; -+ -+io_error: -+ -+ return result; -+} -+ -+/* Unluckily (for us) form 2.4.19 -> 2.4.20 the nfs-proc's where -+ * changed and expect now a proper file-mapping page, where index -+ * encodes the offset alone. -+ * -+ * What we do: we save the original value of page->index, initialize -+ * page->index to what the NFS/sun-rpc subsystem expects and restore -+ * the index later. -+ */ -+static int nfs_rw_swap_page(int rw, struct page *page, -+ unsigned long offset, void *dptr) -+{ -+ int error; -+ struct nfs_swap_data *data = dptr; -+ unsigned long alloc_flag = current->flags & PF_MEMALLOC; -+ unsigned long page_index; -+ -+ if (!PageLocked(page)) -+ panic("nfs_rw_swap_page: page not locked for I/O"); -+ -+ /* prevent memory deadlocks */ -+ if (!(current->flags & PF_MEMALLOC)) { -+ dprintk("nfs_rw_swap_page: Setting PF_MEMALLOC\n"); -+ } -+ current->flags |= PF_MEMALLOC; -+ -+ /* now tweak the page->index field ... */ -+ page_index = page->index; -+ page->index = ((loff_t)offset*(loff_t)PAGE_SIZE) >> PAGE_CACHE_SHIFT; -+ -+ if (rw == WRITE) { -+ error = nfs_write_swap_page(page, -+ data->server, -+ data->inode, -+ data->file); -+ } else { -+ error = nfs_read_swap_page(page, -+ data->server, -+ data->inode, -+ data->file); -+ } -+ -+ if (!alloc_flag) { -+ current->flags &= ~PF_MEMALLOC; -+ } -+ -+ /* now restore the page->index field ... */ -+ page->index = page_index; -+ -+ if (error) { -+ /* Must mark the page invalid after I/O error */ -+ SetPageError(page); -+ ClearPageUptodate(page); -+ } else { -+ ClearPageError(page); -+ SetPageUptodate(page); -+ } -+ -+ if (!error) { /* in case of an error rw_swap_page() likes to unlock -+ * itself. -+ */ -+ UnlockPage(page); -+ } -+ -+ return error < 0 ? 0 : 1; -+} -+ -+static int is_nfsfile_swapping(unsigned int flags, -+ struct file * swapf, -+ void * data) -+{ -+ struct file * filp = (struct file *) data; -+ -+ /* Only check filp's that don't match the one already opened -+ * for us by sys_swapon(). Otherwise, we will always flag a -+ * busy swap file. -+ */ -+ -+ if (swapf != filp) { -+ if (filp->f_dentry->d_inode == swapf->f_dentry->d_inode) -+ return 1; -+ } -+ return 0; -+} -+ -+static int nfs_swap_open(struct file *swapf, void **dptr) -+{ -+ int error = 0; -+ int swapfilesize; -+ struct nfs_swap_data *data; -+ int on = 1; -+ mm_segment_t fs; -+ struct inode *inode = swapf->f_dentry->d_inode; -+ -+ MOD_INC_USE_COUNT; -+ -+ if (!S_ISREG(inode->i_mode)) { -+ dprintk("nfs_swap_open: can't handle this swap file: %s\n", -+ swapf->f_dentry->d_name.name); -+ error = 0; /* not for us */ -+ goto bad_swap; -+ } -+ /* determine whether this file really is located on an NFS mounted -+ * volume -+ */ -+ if (!inode->i_sb || inode->i_sb->s_magic != NFS_SUPER_MAGIC) { -+ dprintk("nfs_swap_open: %s is not an NFS file.\n", -+ swapf->f_dentry->d_name.name); -+ error = 0; /* not for us */ -+ goto bad_swap; -+ } -+ -+ if (swap_run_test(is_nfsfile_swapping, swapf)) { -+ dprintk("nfs_swap_open: already swapping to %s\n", -+ swapf->f_dentry->d_name.name); -+ error = -EBUSY; -+ goto bad_swap; -+ } -+ swapfilesize = inode->i_size >> PAGE_SHIFT; -+ if ((data = kmalloc(sizeof(*data), GFP_KERNEL)) == NULL) { -+ error = -ENOMEM; -+ goto bad_swap; -+ } -+ data->file = swapf; -+ data->inode = inode; -+ data->server = NFS_SERVER(inode); -+ data->socket = data->server->client->cl_xprt->sock; -+ -+ /* set socket option SO_SWAPPING */ -+ fs = get_fs(); -+ set_fs(KERNEL_DS); -+ error = sock_setsockopt(data->socket, SOL_SOCKET, SO_SWAPPING, -+ (char *)&on, sizeof(on)); -+ set_fs(fs); -+ if (error) { -+ dprintk("nfs_swap_open: error setting SO_SWAPPING\n"); -+ goto bad_swap_2; -+ } -+ -+ *dptr = data; -+ return swapfilesize; -+ -+ bad_swap_2: -+ kfree(data); -+ bad_swap: -+ MOD_DEC_USE_COUNT; -+ return error; -+} -+ -+static int nfs_swap_release(struct file *swapf, void *dptr) -+{ -+ struct nfs_swap_data *data = (struct nfs_swap_data *)dptr; -+ int off = 0; -+ mm_segment_t fs; -+ int error; -+ -+#if 1 -+ if (swapf != data->file || -+ swapf->f_dentry->d_inode != data->inode || -+ !swapf->f_dentry->d_inode->i_sb || -+ swapf->f_dentry->d_inode->i_sb->s_magic != NFS_SUPER_MAGIC || -+ NFS_SERVER(swapf->f_dentry->d_inode) != data->server || -+ data->socket != data->server->client->cl_xprt->sock) { -+ panic("nfs_swap_release: nfs swap data messed up"); -+ } -+#endif -+ -+ /* remove socket option SO_SWAPPING */ -+ fs = get_fs(); -+ set_fs(KERNEL_DS); -+ error = sock_setsockopt(data->socket, SOL_SOCKET, SO_SWAPPING, -+ (char *)&off, sizeof(off)); -+ set_fs(fs); -+ if (error) { -+ dprintk("nfs_swap_open: error clearing SO_SWAPPING\n"); -+ } -+ kfree(data); -+ MOD_DEC_USE_COUNT; -+ return error; -+} -+ -+static struct swap_ops nfs_swap_ops = { -+ open: nfs_swap_open, -+ release: nfs_swap_release, -+ rw_page: nfs_rw_swap_page -+}; -+ -+int __init nfs_swap_init(void) -+{ -+ (void)register_swap_method(NFS_SWAP_ID, &nfs_swap_ops); -+ return 0; -+} -+ -+void __exit nfs_swap_exit(void) -+{ -+ unregister_swap_method(NFS_SWAP_ID); -+} -+ -+module_init(nfs_swap_init) -+module_exit(nfs_swap_exit) -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("(c) 1996-2002 cH (Claus-Justus Heine)"); -+MODULE_DESCRIPTION("Swapping to files located on volumes mounted via NFS"); -diff -Nurb src/linux/linux.orig/fs/nfs/read.c src/linux/linux/fs/nfs/read.c ---- src/linux/linux.orig/fs/nfs/read.c 2003-07-04 04:12:08.000000000 -0400 -+++ src/linux/linux/fs/nfs/read.c 2004-05-31 02:18:03.000000000 -0400 -@@ -50,11 +50,6 @@ - */ - static void nfs_readpage_result(struct rpc_task *task); - --/* Hack for future NFS swap support */ --#ifndef IS_SWAPFILE --# define IS_SWAPFILE(inode) (0) --#endif -- - static kmem_cache_t *nfs_rdata_cachep; - - static __inline__ struct nfs_read_data *nfs_readdata_alloc(void) -@@ -92,7 +87,6 @@ - int rsize = NFS_SERVER(inode)->rsize; - int result; - int count = PAGE_CACHE_SIZE; -- int flags = IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0; - int eof; - - dprintk("NFS: nfs_readpage_sync(%p)\n", page); -@@ -114,7 +108,7 @@ - offset, rsize, page); - - lock_kernel(); -- result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags, -+ result = NFS_PROTO(inode)->read(inode, cred, &fattr, 0, - offset, rsize, page, &eof); - nfs_refresh_inode(inode, &fattr); - unlock_kernel(); -@@ -246,7 +240,7 @@ - task = &data->task; - - /* N.B. Do we need to test? Never called for swapfile inode */ -- flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); -+ flags = RPC_TASK_ASYNC; - - nfs_read_rpcsetup(head, data); - -@@ -476,8 +470,6 @@ - } - - error = nfs_readpage_sync(file, inode, page); -- if (error < 0 && IS_SWAPFILE(inode)) -- printk("Aiee.. nfs swap-in of page failed!\n"); - out: - return error; - -diff -Nurb src/linux/linux.orig/fs/nfs/write.c src/linux/linux/fs/nfs/write.c ---- src/linux/linux.orig/fs/nfs/write.c 2003-07-04 04:12:08.000000000 -0400 -+++ src/linux/linux/fs/nfs/write.c 2004-05-31 02:20:47.000000000 -0400 -@@ -3,7 +3,6 @@ - #include - #include - #include --#include - #include - #include - -@@ -46,11 +45,6 @@ - static void nfs_commit_done(struct rpc_task *); - #endif - --/* Hack for future NFS swap support */ --#ifndef IS_SWAPFILE --# define IS_SWAPFILE(inode) (0) --#endif -- - static kmem_cache_t *nfs_wdata_cachep; - - static __inline__ struct nfs_write_data *nfs_writedata_alloc(void) -@@ -82,7 +76,7 @@ - * For the moment, we just call nfs_refresh_inode(). - */ - static __inline__ int --nfs_write_attributes(struct inode *inode, struct nfs_fattr *fattr) -+__nfs_write_attributes(struct inode *inode, struct nfs_fattr *fattr) - { - if ((fattr->valid & NFS_ATTR_FATTR) && !(fattr->valid & NFS_ATTR_WCC)) { - fattr->pre_size = NFS_CACHE_ISIZE(inode); -@@ -93,6 +87,11 @@ - return nfs_refresh_inode(inode, fattr); - } - -+int nfs_write_attributes(struct inode *inode, struct nfs_fattr *fattr) -+{ -+ return __nfs_write_attributes(inode, fattr); -+} -+ - /* - * Write a page synchronously. - * Offset is the data offset within the page. -@@ -104,8 +103,7 @@ - struct rpc_cred *cred = NULL; - loff_t base; - unsigned int wsize = NFS_SERVER(inode)->wsize; -- int result, refresh = 0, written = 0, flags; -- u8 *buffer; -+ int result, refresh = 0, written = 0; - struct nfs_fattr fattr; - struct nfs_writeverf verf; - -@@ -121,15 +119,14 @@ - - base = page_offset(page) + offset; - -- flags = ((IS_SWAPFILE(inode)) ? NFS_RW_SWAP : 0) | NFS_RW_SYNC; -- - do { -- if (count < wsize && !IS_SWAPFILE(inode)) -+ if (count < wsize) - wsize = count; - -- result = NFS_PROTO(inode)->write(inode, cred, &fattr, flags, -+ result = NFS_PROTO(inode)->write(inode, cred, &fattr, -+ NFS_RW_SYNC, - offset, wsize, page, &verf); -- nfs_write_attributes(inode, &fattr); -+ __nfs_write_attributes(inode, &fattr); - - if (result < 0) { - /* Must mark the page invalid after I/O error */ -@@ -140,7 +137,6 @@ - printk("NFS: short write, wsize=%u, result=%d\n", - wsize, result); - refresh = 1; -- buffer += wsize; - base += wsize; - offset += wsize; - written += wsize; -@@ -979,7 +975,7 @@ - } - #endif - -- nfs_write_attributes(inode, resp->fattr); -+ __nfs_write_attributes(inode, resp->fattr); - while (!list_empty(&data->pages)) { - req = nfs_list_entry(data->pages.next); - nfs_list_remove_request(req); -@@ -1133,7 +1129,7 @@ - if (nfs_async_handle_jukebox(task)) - return; - -- nfs_write_attributes(inode, resp->fattr); -+ __nfs_write_attributes(inode, resp->fattr); - while (!list_empty(&data->pages)) { - req = nfs_list_entry(data->pages.next); - nfs_list_remove_request(req); -diff -Nurb src/linux/linux.orig/include/linux/fs.h src/linux/linux/include/linux/fs.h ---- src/linux/linux.orig/include/linux/fs.h 2004-05-31 02:06:19.000000000 -0400 -+++ src/linux/linux/include/linux/fs.h 2004-05-31 02:18:03.000000000 -0400 -@@ -1500,6 +1500,10 @@ - extern int inode_change_ok(struct inode *, struct iattr *); - extern int inode_setattr(struct inode *, struct iattr *); - -+/* for swapping to block devices */ -+void create_empty_buffers(struct page *page, kdev_t dev, unsigned long blocksize); -+void end_buffer_io_async(struct buffer_head * bh, int uptodate); -+ - /* - * Common dentry functions for inclusion in the VFS - * or in other stackable file systems. Some of these -diff -Nurb src/linux/linux.orig/include/linux/nfs_fs.h src/linux/linux/include/linux/nfs_fs.h ---- src/linux/linux.orig/include/linux/nfs_fs.h 2004-05-31 02:06:28.000000000 -0400 -+++ src/linux/linux/include/linux/nfs_fs.h 2004-05-31 02:18:03.000000000 -0400 -@@ -40,8 +40,8 @@ - */ - #define NFS_MAX_DIRCACHE 16 - --#define NFS_MAX_FILE_IO_BUFFER_SIZE 32768 --#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096 -+#define NFS_MAX_FILE_IO_BUFFER_SIZE (8*PAGE_SIZE) -+#define NFS_DEF_FILE_IO_BUFFER_SIZE PAGE_SIZE - - /* - * The upper limit on timeouts for the exponential backoff algorithm. -@@ -205,6 +205,8 @@ - extern int nfs_writepage(struct page *); - extern int nfs_flush_incompatible(struct file *file, struct page *page); - extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); -+extern int nfs_write_attributes(struct inode *inode, struct nfs_fattr *fattr); -+ - /* - * Try to write back everything synchronously (but check the - * return value!) -@@ -375,6 +377,7 @@ - #define NFSDBG_XDR 0x0020 - #define NFSDBG_FILE 0x0040 - #define NFSDBG_ROOT 0x0080 -+#define NFSDBG_SWAP 0x0100 - #define NFSDBG_ALL 0xFFFF - - #ifdef __KERNEL__ -diff -Nurb src/linux/linux.orig/include/linux/slab.h src/linux/linux/include/linux/slab.h ---- src/linux/linux.orig/include/linux/slab.h 2004-05-31 02:06:19.000000000 -0400 -+++ src/linux/linux/include/linux/slab.h 2004-05-31 02:18:03.000000000 -0400 -@@ -39,6 +39,7 @@ - #define SLAB_HWCACHE_ALIGN 0x00002000UL /* align objs on a h/w cache lines */ - #define SLAB_CACHE_DMA 0x00004000UL /* use GFP_DMA memory */ - #define SLAB_MUST_HWCACHE_ALIGN 0x00008000UL /* force alignment */ -+#define SLAB_LOW_GFP_ORDER 0x00010000UL /* use as low a gfp order as possible */ - - /* flags passed to a constructor func */ - #define SLAB_CTOR_CONSTRUCTOR 0x001UL /* if not set, then deconstructor */ -diff -Nurb src/linux/linux.orig/include/linux/swap.h src/linux/linux/include/linux/swap.h ---- src/linux/linux.orig/include/linux/swap.h 2004-05-31 02:06:19.000000000 -0400 -+++ src/linux/linux/include/linux/swap.h 2004-05-31 02:18:03.000000000 -0400 -@@ -58,15 +58,29 @@ - #define SWAP_MAP_MAX 0x7fff - #define SWAP_MAP_BAD 0x8000 - -+struct swap_ops { -+ int (*open)(struct file *swapf, void **data); -+ int (*release)(struct file *swapf, void *data); -+ int (*rw_page)(int rw, -+ struct page *page, unsigned long offset, void *data); -+}; -+ -+struct swap_method { -+ struct swap_method *next; -+ char * name; -+ struct swap_ops *ops; -+ int use_count; -+}; -+ - /* - * The in-memory structure used to track swap areas. - */ - struct swap_info_struct { - unsigned int flags; -- kdev_t swap_device; -+ struct file *swap_file; -+ struct swap_method *method; -+ void *data; - spinlock_t sdev_lock; -- struct dentry * swap_file; -- struct vfsmount *swap_vfsmnt; - unsigned short * swap_map; - unsigned int lowest_bit; - unsigned int highest_bit; -@@ -141,11 +155,15 @@ - extern int total_swap_pages; - extern unsigned int nr_swapfiles; - extern struct swap_info_struct swap_info[]; --extern int is_swap_partition(kdev_t); -+extern int register_swap_method(char *name, struct swap_ops *ops); -+extern int unregister_swap_method(char *name); -+extern int swap_run_test(int (*test_fct)(unsigned int flags, -+ struct file *swap_file, -+ void *testdata), void *testdata); - extern void si_swapinfo(struct sysinfo *); - extern swp_entry_t get_swap_page(void); --extern void get_swaphandle_info(swp_entry_t, unsigned long *, kdev_t *, -- struct inode **); -+struct swap_method *get_swaphandle_info(swp_entry_t entry, -+ unsigned long *offset, void **data); - extern int swap_duplicate(swp_entry_t); - extern int swap_count(struct page *); - extern int valid_swaphandles(swp_entry_t, unsigned long *); -diff -Nurb src/linux/linux.orig/include/net/netswapping.h src/linux/linux/include/net/netswapping.h ---- src/linux/linux.orig/include/net/netswapping.h 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/include/net/netswapping.h 2004-05-31 02:18:03.000000000 -0400 -@@ -0,0 +1,47 @@ -+#ifndef _LINUX_NETSWAPPING_H -+#define _LINUX_NETSWAPPING_H -+ -+#include -+#include -+ -+/* It is a mess. Socket options are defined in asm-ARCH/socket.h */ -+ -+#define SO_SWAPPING 0x00100000 /* hopefully not used by anybody else */ -+ -+#ifdef __KERNEL__ -+ -+#define CTL_NETSWAP 0x00100000 -+ -+enum { -+ NET_SWAP_DROPPED = 1, -+ NET_SWAP_DROP_THRESHOLD = 2, -+ NET_SWAP_SOCK_COUNT = 3 -+}; -+ -+extern unsigned int netswap_free_pages_min; -+extern int netswap_sock_count; -+extern unsigned int netswap_dropped; -+ -+/* this is "#defined" and not inline because sock.h includes us, but we need -+ * the "struct sock" definition. -+ */ -+#define netswap_low_memory(sk, skb) \ -+({ \ -+ int _ret = 0; \ -+ \ -+ if (netswap_sock_count > 0 && /* anybody swapping via network? */ \ -+ !(sk)->swapping && /* but we are not needed for swapping */ \ -+ nr_free_pages() < netswap_free_pages_min) { /* so drop us */ \ -+ printk("netswap_low_memory: " \ -+ "dropping skb 0x%p@0x%p\n", skb, sk); \ -+ netswap_dropped ++; \ -+ _ret = 1; \ -+ } \ -+ _ret; \ -+}) -+ -+extern int __init netswap_init(void); -+ -+#endif -+ -+#endif -diff -Nurb src/linux/linux.orig/include/net/sock.h src/linux/linux/include/net/sock.h ---- src/linux/linux.orig/include/net/sock.h 2004-05-31 02:07:17.000000000 -0400 -+++ src/linux/linux/include/net/sock.h 2004-05-31 02:18:03.000000000 -0400 -@@ -103,6 +103,10 @@ - #include - #endif - -+#ifdef CONFIG_NETSWAP -+#include -+#endif -+ - #include - #include - -@@ -536,6 +540,12 @@ - no_check, - broadcast, - bsdism; -+#ifdef CONFIG_NETSWAP -+ /* Increased by SO_SWAPPING with arg != 0, decreased by -+ * SO_SWAPPING with arg 0 -+ */ -+ int swapping; -+#endif - unsigned char debug; - unsigned char rcvtstamp; - unsigned char use_write_queue; -@@ -1165,6 +1175,11 @@ - return err; /* Toss packet */ - } - #endif /* CONFIG_FILTER */ -+#ifdef CONFIG_NETSWAP -+ /* an inline function defined in net/netswapping.h */ -+ if (netswap_low_memory(sk, skb)) -+ return -ENOMEM; -+#endif /* CONFIG_NETSWAP */ - - skb->dev = NULL; - skb_set_owner_r(skb, sk); -diff -Nurb src/linux/linux.orig/kernel/ksyms.c src/linux/linux/kernel/ksyms.c ---- src/linux/linux.orig/kernel/ksyms.c 2004-05-31 02:02:43.000000000 -0400 -+++ src/linux/linux/kernel/ksyms.c 2004-05-31 02:18:03.000000000 -0400 -@@ -41,6 +41,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -127,6 +128,11 @@ - EXPORT_SYMBOL(kmap_prot); - EXPORT_SYMBOL(kmap_pte); - #endif -+EXPORT_SYMBOL(nr_free_pages); -+/* EXPORT_SYMBOL(freepages); */ -+EXPORT_SYMBOL(register_swap_method); -+EXPORT_SYMBOL(unregister_swap_method); -+EXPORT_SYMBOL(swap_run_test); - - /* filesystem internal functions */ - EXPORT_SYMBOL(def_blk_fops); -@@ -531,7 +537,7 @@ - EXPORT_SYMBOL(make_bad_inode); - EXPORT_SYMBOL(is_bad_inode); - EXPORT_SYMBOL(event); --EXPORT_SYMBOL(brw_page); -+EXPORT_SYMBOL(end_buffer_io_async); - EXPORT_SYMBOL(__inode_dir_notify); - - #ifdef CONFIG_UID16 -diff -Nurb src/linux/linux.orig/mm/page_io.c src/linux/linux/mm/page_io.c ---- src/linux/linux.orig/mm/page_io.c 2003-07-04 04:12:29.000000000 -0400 -+++ src/linux/linux/mm/page_io.c 2004-05-31 02:18:03.000000000 -0400 -@@ -36,11 +36,8 @@ - static int rw_swap_page_base(int rw, swp_entry_t entry, struct page *page) - { - unsigned long offset; -- int zones[PAGE_SIZE/512]; -- int zones_used; -- kdev_t dev = 0; -- int block_size; -- struct inode *swapf = 0; -+ struct swap_method *method; -+ void *data; - - if (rw == READ) { - ClearPageUptodate(page); -@@ -48,30 +45,11 @@ - } else - kstat.pswpout++; - -- get_swaphandle_info(entry, &offset, &dev, &swapf); -- if (dev) { -- zones[0] = offset; -- zones_used = 1; -- block_size = PAGE_SIZE; -- } else if (swapf) { -- int i, j; -- unsigned int block = offset -- << (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits); -- -- block_size = swapf->i_sb->s_blocksize; -- for (i=0, j=0; j< PAGE_SIZE ; i++, j += block_size) -- if (!(zones[i] = bmap(swapf,block++))) { -- printk("rw_swap_page: bad swap file\n"); -- return 0; -- } -- zones_used = i; -- dev = swapf->i_dev; -- } else { -+ method = get_swaphandle_info(entry, &offset, &data); -+ if (!method || !method->ops->rw_page(rw, page, offset, data)) { - return 0; - } - -- /* block_size == PAGE_SIZE/zones_used */ -- brw_page(rw, page, dev, zones, block_size); - return 1; - } - -diff -Nurb src/linux/linux.orig/mm/slab.c src/linux/linux/mm/slab.c ---- src/linux/linux.orig/mm/slab.c 2003-07-04 04:12:29.000000000 -0400 -+++ src/linux/linux/mm/slab.c 2004-05-31 02:18:03.000000000 -0400 -@@ -111,10 +111,12 @@ - # define CREATE_MASK (SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \ - SLAB_POISON | SLAB_HWCACHE_ALIGN | \ - SLAB_NO_REAP | SLAB_CACHE_DMA | \ -- SLAB_MUST_HWCACHE_ALIGN) -+ SLAB_MUST_HWCACHE_ALIGN | \ -+ SLAB_LOW_GFP_ORDER) - #else - # define CREATE_MASK (SLAB_HWCACHE_ALIGN | SLAB_NO_REAP | \ -- SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN) -+ SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN | \ -+ SLAB_LOW_GFP_ORDER) - #endif - - /* -@@ -247,8 +249,13 @@ - }; - - /* internal c_flags */ --#define CFLGS_OFF_SLAB 0x010000UL /* slab management in own cache */ --#define CFLGS_OPTIMIZE 0x020000UL /* optimized slab lookup */ -+#define CFLGS_OFF_SLAB 0x020000UL /* slab management in own cache */ -+#define CFLGS_OPTIMIZE 0x040000UL /* optimized slab lookup */ -+#define CFLGS_MASK (CFLGS_OFF_SLAB | CFLGS_OPTIMIZE) -+ -+#if (CFLGS_MASK & CREATE_MASK) -+# error BUG: internal and external SLAB flags overlap -+#endif - - /* c_dflags (dynamic flags). Need to hold the spinlock to access this member */ - #define DFLGS_GROWN 0x000001UL /* don't reap a recently grown */ -@@ -452,7 +459,12 @@ - snprintf(name, sizeof(name), "size-%Zd",sizes->cs_size); - if (!(sizes->cs_cachep = - kmem_cache_create(name, sizes->cs_size, -- 0, SLAB_HWCACHE_ALIGN, NULL, NULL))) { -+ 0, -+#if CONFIG_NETSWAP -+ SLAB_LOW_GFP_ORDER| /* sorry */ -+#endif -+ SLAB_HWCACHE_ALIGN, -+ NULL, NULL))) { - BUG(); - } - -@@ -731,6 +743,8 @@ - break; - if (!cachep->num) - goto next; -+ if (cachep->gfporder == 0 && (flags & SLAB_LOW_GFP_ORDER)) -+ break; - if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit) { - /* Oops, this num of objs will cause problems. */ - cachep->gfporder--; -diff -Nurb src/linux/linux.orig/mm/swapfile.c src/linux/linux/mm/swapfile.c ---- src/linux/linux.orig/mm/swapfile.c 2003-07-04 04:12:29.000000000 -0400 -+++ src/linux/linux/mm/swapfile.c 2004-05-31 02:18:03.000000000 -0400 -@@ -11,12 +11,17 @@ - #include - #include - #include /* for blk_size */ -+#include - #include - #include - #include - - #include - -+#ifdef CONFIG_KMOD -+#include -+#endif -+ - spinlock_t swaplock = SPIN_LOCK_UNLOCKED; - unsigned int nr_swapfiles; - int total_swap_pages; -@@ -31,8 +36,78 @@ - - struct swap_info_struct swap_info[MAX_SWAPFILES]; - -+static struct swap_method *swap_methods = NULL; -+ - #define SWAPFILE_CLUSTER 256 - -+int register_swap_method(char *name, struct swap_ops *ops) -+{ -+ struct swap_method *pos; -+ struct swap_method *new; -+ int result = 0; -+ -+ lock_kernel(); -+ -+ for (pos = swap_methods; pos; pos = pos->next) { -+ if (strcmp(pos->name, name) == 0) { -+ printk(KERN_ERR "register_swap_method: " -+ "method %s already registered\n", name); -+ result = -EBUSY; -+ goto out; -+ } -+ } -+ -+ if (!(new = kmalloc(sizeof(*new), GFP_KERNEL))) { -+ printk(KERN_ERR "register_swap_method: " -+ "no memory for new method \"%s\"\n", name); -+ result = -ENOMEM; -+ goto out; -+ } -+ -+ new->name = name; -+ new->ops = ops; -+ new->use_count = 0; -+ -+ /* ok, insert at top of list */ -+ printk("register_swap_method: method %s\n", name); -+ new->next = swap_methods; -+ swap_methods = new; -+ out: -+ unlock_kernel(); -+ return result; -+} -+ -+int unregister_swap_method(char *name) -+{ -+ struct swap_method **method, *next; -+ int result = 0; -+ -+ lock_kernel(); -+ -+ for (method = &swap_methods; *method; method = &(*method)->next) { -+ if (strcmp((*method)->name, name) == 0) { -+ if ((*method)->use_count > 0) { -+ printk(KERN_ERR "unregister_swap_method: " -+ "method \"%s\" is in use\n", name); -+ result = -EBUSY; -+ goto out; -+ } -+ -+ next = (*method)->next; -+ kfree(*method); -+ *method = next; -+ printk("unregister_swap_method: method %s\n", name); -+ goto out; -+ } -+ } -+ /* not found */ -+ printk("unregister_swap_method: no such method %s\n", name); -+ result = -ENOENT; -+ out: -+ unlock_kernel(); -+ return result; -+} -+ - static inline int scan_swap_map(struct swap_info_struct *si) - { - unsigned long offset; -@@ -711,13 +786,14 @@ - struct nameidata nd; - int i, type, prev; - int err; -+ struct file *swap_file; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; - - err = user_path_walk(specialfile, &nd); - if (err) -- goto out; -+ return err; - - lock_kernel(); - prev = -1; -@@ -725,15 +801,20 @@ - for (type = swap_list.head; type >= 0; type = swap_info[type].next) { - p = swap_info + type; - if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) { -- if (p->swap_file == nd.dentry) -+ if (p->swap_file && -+ p->swap_file->f_dentry == nd.dentry) - break; - } - prev = type; - } - err = -EINVAL; -+ /* p->swap_file contains all needed info, no need to keep nd, so -+ * release it now. -+ */ -+ path_release(&nd); - if (type < 0) { - swap_list_unlock(); -- goto out_dput; -+ goto out; - } - - if (prev < 0) { -@@ -767,32 +848,30 @@ - total_swap_pages += p->pages; - p->flags = SWP_WRITEOK; - swap_list_unlock(); -- goto out_dput; -+ goto out; - } -- if (p->swap_device) -- blkdev_put(p->swap_file->d_inode->i_bdev, BDEV_SWAP); -- path_release(&nd); - -+ if (p->method->ops->release) -+ p->method->ops->release(p->swap_file, p->data); - swap_list_lock(); - swap_device_lock(p); -- nd.mnt = p->swap_vfsmnt; -- nd.dentry = p->swap_file; -- p->swap_vfsmnt = NULL; -+ p->method->use_count --; -+ p->method = NULL; -+ p->data = NULL; -+ swap_file = p->swap_file; - p->swap_file = NULL; -- p->swap_device = 0; - p->max = 0; - swap_map = p->swap_map; - p->swap_map = NULL; - p->flags = 0; - swap_device_unlock(p); - swap_list_unlock(); -+ filp_close(swap_file, NULL); - vfree(swap_map); - err = 0; - --out_dput: -- unlock_kernel(); -- path_release(&nd); - out: -+ unlock_kernel(); - return err; - } - -@@ -805,18 +884,17 @@ - if (!page) - return -ENOMEM; - -- len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n"); -+ len += sprintf(buf, "%-32s%-16s%-8s%-8sPriority\n", -+ "Filename", "Type", "Size", "Used"); - for (i = 0 ; i < nr_swapfiles ; i++, ptr++) { - if ((ptr->flags & SWP_USED) && ptr->swap_map) { -- char * path = d_path(ptr->swap_file, ptr->swap_vfsmnt, -+ char * path = d_path(ptr->swap_file->f_dentry, -+ ptr->swap_file->f_vfsmnt, - page, PAGE_SIZE); - - len += sprintf(buf + len, "%-31s ", path); - -- if (!ptr->swap_device) -- len += sprintf(buf + len, "file\t\t"); -- else -- len += sprintf(buf + len, "partition\t"); -+ len += sprintf(buf + len, "%-15s ", ptr->method->name); - - usedswap = 0; - for (j = 0; j < ptr->max; ++j) -@@ -827,7 +905,7 @@ - default: - usedswap++; - } -- len += sprintf(buf + len, "%d\t%d\t%d\n", ptr->pages << (PAGE_SHIFT - 10), -+ len += sprintf(buf + len, "%-8d%-8d%d\n", ptr->pages << (PAGE_SHIFT - 10), - usedswap << (PAGE_SHIFT - 10), ptr->prio); - } - } -@@ -835,18 +913,55 @@ - return len; - } - --int is_swap_partition(kdev_t dev) { -+/* apply a test function to all active swap objects. E.g. for checking -+ * whether a partition is used for swapping -+ */ -+int swap_run_test(int (*test_fct)(unsigned int flags, -+ struct file * swap_file, -+ void *testdata), void *testdata) -+{ - struct swap_info_struct *ptr = swap_info; - int i; - - for (i = 0 ; i < nr_swapfiles ; i++, ptr++) { -- if (ptr->flags & SWP_USED) -- if (ptr->swap_device == dev) -+ if (ptr->swap_file && -+ test_fct(ptr->flags, ptr->swap_file, testdata)) - return 1; - } - return 0; - } - -+/* Walk through the list of known swap method until somebody wants to -+ * handle this file. Pick the first one which claims to be able to -+ * swap to this kind of file. -+ * -+ * return value: < 0: error, 0: not found, > 0: swapfilesize -+ */ -+int find_swap_method(struct file *swap_file, -+ struct swap_info_struct *p) -+{ -+ int swapfilesize = 0; -+ struct swap_method *method; -+ -+ p->method = NULL; -+ for (method = swap_methods; method; method = method->next) { -+ swapfilesize = method->ops->open(swap_file, &p->data); -+ if (swapfilesize == 0) { -+ continue; -+ } -+ if (swapfilesize > 0) { -+ p->method = method; -+ p->method->use_count ++; -+ p->swap_file = swap_file; -+ break; -+ } -+ if (swapfilesize < 0) { -+ break; -+ } -+ } -+ return swapfilesize; -+} -+ - /* - * Written 01/25/92 by Simmule Turner, heavily changed by Linus. - * -@@ -855,8 +970,6 @@ - asmlinkage long sys_swapon(const char * specialfile, int swap_flags) - { - struct swap_info_struct * p; -- struct nameidata nd; -- struct inode * swap_inode; - unsigned int type; - int i, j, prev; - int error; -@@ -866,8 +979,9 @@ - int nr_good_pages = 0; - unsigned long maxpages = 1; - int swapfilesize; -- struct block_device *bdev = NULL; - unsigned short *swap_map; -+ char * tmp_specialfile; -+ struct file *swap_file; - - if (!capable(CAP_SYS_ADMIN)) - return -EPERM; -@@ -886,8 +1000,7 @@ - nr_swapfiles = type+1; - p->flags = SWP_USED; - p->swap_file = NULL; -- p->swap_vfsmnt = NULL; -- p->swap_device = 0; -+ p->method = NULL; - p->swap_map = NULL; - p->lowest_bit = 0; - p->highest_bit = 0; -@@ -901,53 +1014,56 @@ - p->prio = --least_priority; - } - swap_list_unlock(); -- error = user_path_walk(specialfile, &nd); -- if (error) -+ -+ /* Open the swap using filp_open. Bail out on any errors. */ -+ tmp_specialfile = getname(specialfile); -+ if (IS_ERR(tmp_specialfile)) { -+ error = PTR_ERR(tmp_specialfile); - goto bad_swap_2; -+ } -+ p->swap_file = filp_open(tmp_specialfile, O_RDWR, 0600); -+ putname(tmp_specialfile); -+ if (IS_ERR(p->swap_file)) { -+ error = PTR_ERR(p->swap_file); -+ goto bad_swap_1; -+ } - -- p->swap_file = nd.dentry; -- p->swap_vfsmnt = nd.mnt; -- swap_inode = nd.dentry->d_inode; - error = -EINVAL; - -- if (S_ISBLK(swap_inode->i_mode)) { -- kdev_t dev = swap_inode->i_rdev; -- struct block_device_operations *bdops; -- devfs_handle_t de; -- -- p->swap_device = dev; -- set_blocksize(dev, PAGE_SIZE); -- -- bd_acquire(swap_inode); -- bdev = swap_inode->i_bdev; -- de = devfs_get_handle_from_inode(swap_inode); -- bdops = devfs_get_ops(de); /* Increments module use count */ -- if (bdops) bdev->bd_op = bdops; -- -- error = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_SWAP); -- devfs_put_ops(de);/*Decrement module use count now we're safe*/ -- if (error) -- goto bad_swap_2; -- set_blocksize(dev, PAGE_SIZE); -- error = -ENODEV; -- if (!dev || (blk_size[MAJOR(dev)] && -- !blk_size[MAJOR(dev)][MINOR(dev)])) -- goto bad_swap; -- swapfilesize = 0; -- if (blk_size[MAJOR(dev)]) -- swapfilesize = blk_size[MAJOR(dev)][MINOR(dev)] -- >> (PAGE_SHIFT - 10); -- } else if (S_ISREG(swap_inode->i_mode)) -- swapfilesize = swap_inode->i_size >> PAGE_SHIFT; -- else -- goto bad_swap; -+ swapfilesize = find_swap_method(p->swap_file, p); -+ if (swapfilesize < 0) { -+ error = swapfilesize; -+ goto bad_swap_1; -+ } -+#ifdef CONFIG_KMOD -+ if (swapfilesize == 0) { -+ (void)request_module("swapfile-mod"); -+ -+ swapfilesize = find_swap_method(p->swap_file, p); -+ if (swapfilesize < 0) { -+ error = swapfilesize; -+ goto bad_swap_1; -+ } -+ } -+#endif -+ if (swapfilesize == 0) { -+ printk("Don't know how to swap to this kind of file\n"); -+ goto bad_swap_1; /* free swap map */ -+ } -+ -+ /* After this point, the swap-file has been opened by the swap -+ * method. We must make sure to use the bad_swap label for any -+ * errors. -+ */ - - error = -EBUSY; - for (i = 0 ; i < nr_swapfiles ; i++) { - struct swap_info_struct *q = &swap_info[i]; - if (i == type || !q->swap_file) - continue; -- if (swap_inode->i_mapping == q->swap_file->d_inode->i_mapping) -+ if (p->swap_file->f_dentry->d_inode->i_mapping -+ == -+ q->swap_file->f_dentry->d_inode->i_mapping) - goto bad_swap; - } - -@@ -1083,17 +1199,27 @@ - swap_list_unlock(); - error = 0; - goto out; -+ - bad_swap: -- if (bdev) -- blkdev_put(bdev, BDEV_SWAP); -+ if (p->method->ops->release) -+ p->method->ops->release(p->swap_file, p->data); -+ swap_list_lock(); -+ p->method->use_count --; -+ p->method = NULL; -+ p->data = NULL; -+ swap_list_unlock(); -+ -+bad_swap_1: -+ swap_list_lock(); -+ swap_file = p->swap_file; -+ p->swap_file = NULL; -+ swap_list_unlock(); -+ filp_close(swap_file, NULL); -+ - bad_swap_2: -+ - swap_list_lock(); - swap_map = p->swap_map; -- nd.mnt = p->swap_vfsmnt; -- nd.dentry = p->swap_file; -- p->swap_device = 0; -- p->swap_file = NULL; -- p->swap_vfsmnt = NULL; - p->swap_map = NULL; - p->flags = 0; - if (!(swap_flags & SWAP_FLAG_PREFER)) -@@ -1101,7 +1227,7 @@ - swap_list_unlock(); - if (swap_map) - vfree(swap_map); -- path_release(&nd); -+ - out: - if (swap_header) - free_page((long) swap_header); -@@ -1217,8 +1343,8 @@ - /* - * Prior swap_duplicate protects against swap device deletion. - */ --void get_swaphandle_info(swp_entry_t entry, unsigned long *offset, -- kdev_t *dev, struct inode **swapf) -+struct swap_method *get_swaphandle_info(swp_entry_t entry, -+ unsigned long *offset, void **data) - { - unsigned long type; - struct swap_info_struct *p; -@@ -1226,32 +1352,26 @@ - type = SWP_TYPE(entry); - if (type >= nr_swapfiles) { - printk(KERN_ERR "rw_swap_page: %s%08lx\n", Bad_file, entry.val); -- return; -+ return NULL; - } - - p = &swap_info[type]; - *offset = SWP_OFFSET(entry); - if (*offset >= p->max && *offset != 0) { - printk(KERN_ERR "rw_swap_page: %s%08lx\n", Bad_offset, entry.val); -- return; -+ return NULL; - } - if (p->swap_map && !p->swap_map[*offset]) { - printk(KERN_ERR "rw_swap_page: %s%08lx\n", Unused_offset, entry.val); -- return; -+ return NULL; - } - if (!(p->flags & SWP_USED)) { - printk(KERN_ERR "rw_swap_page: %s%08lx\n", Unused_file, entry.val); -- return; -+ return NULL; - } - -- if (p->swap_device) { -- *dev = p->swap_device; -- } else if (p->swap_file) { -- *swapf = p->swap_file->d_inode; -- } else { -- printk(KERN_ERR "rw_swap_page: no swap file or device\n"); -- } -- return; -+ *data = p->data; -+ return p->method; - } - - /* -diff -Nurb src/linux/linux.orig/net/Config.in src/linux/linux/net/Config.in ---- src/linux/linux.orig/net/Config.in 2003-07-04 04:12:29.000000000 -0400 -+++ src/linux/linux/net/Config.in 2004-05-31 02:18:03.000000000 -0400 -@@ -16,6 +16,9 @@ - fi - bool 'Socket Filtering' CONFIG_FILTER - tristate 'Unix domain sockets' CONFIG_UNIX -+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -+ bool 'Swapping via network sockets (EXPERIMENTAL)' CONFIG_NETSWAP -+fi - bool 'TCP/IP networking' CONFIG_INET - if [ "$CONFIG_INET" = "y" ]; then - source net/ipv4/Config.in -diff -Nurb src/linux/linux.orig/net/Makefile src/linux/linux/net/Makefile ---- src/linux/linux.orig/net/Makefile 2003-07-04 04:12:29.000000000 -0400 -+++ src/linux/linux/net/Makefile 2004-05-31 02:18:03.000000000 -0400 -@@ -51,6 +51,7 @@ - ifeq ($(CONFIG_NET),y) - obj-$(CONFIG_MODULES) += netsyms.o - obj-$(CONFIG_SYSCTL) += sysctl_net.o -+obj-$(CONFIG_NETSWAP) += netswapping.o - endif - - include $(TOPDIR)/Rules.make -diff -Nurb src/linux/linux.orig/net/core/sock.c src/linux/linux/net/core/sock.c ---- src/linux/linux.orig/net/core/sock.c 2003-10-14 04:09:32.000000000 -0400 -+++ src/linux/linux/net/core/sock.c 2004-05-31 02:18:03.000000000 -0400 -@@ -402,6 +402,21 @@ - ret = -ENONET; - break; - #endif -+#ifdef CONFIG_NETSWAP -+ case SO_SWAPPING: -+ if (valbool) { -+ if (!sk->swapping) { -+ netswap_sock_count ++; -+ } -+ sk->swapping ++; -+ } else if (sk->swapping > 0) { -+ sk->swapping --; -+ if (!sk->swapping) { -+ netswap_sock_count --; -+ } -+ } -+ break; -+#endif - /* We implement the SO_SNDLOWAT etc to - not be settable (1003.1g 5.3) */ - default: -@@ -552,6 +567,12 @@ - goto lenout; - } - -+#ifdef CONFIG_NETSWAP -+ case SO_SWAPPING: -+ v.val = sk->swapping; -+ break; -+#endif -+ - /* Dubious BSD thing... Probably nobody even uses it, but - * the UNIX standard wants it for whatever reason... -DaveM - */ -diff -Nurb src/linux/linux.orig/net/ipv4/tcp_ipv4.c src/linux/linux/net/ipv4/tcp_ipv4.c ---- src/linux/linux.orig/net/ipv4/tcp_ipv4.c 2003-10-14 04:09:33.000000000 -0400 -+++ src/linux/linux/net/ipv4/tcp_ipv4.c 2004-05-31 02:18:03.000000000 -0400 -@@ -1657,6 +1657,12 @@ - if (filter && sk_filter(skb, filter)) - goto discard; - #endif /* CONFIG_FILTER */ -+#ifdef CONFIG_NETSWAP -+ /* tcp doesn't use sock_queue_rcv_skb() ... */ -+ /* an inline function defined in net/netswapping.h */ -+ if (netswap_low_memory(sk, skb)) -+ goto discard; -+#endif /* CONFIG_NETSWAP */ - - IP_INC_STATS_BH(IpInDelivers); - -diff -Nurb src/linux/linux.orig/net/ipv6/tcp_ipv6.c src/linux/linux/net/ipv6/tcp_ipv6.c ---- src/linux/linux.orig/net/ipv6/tcp_ipv6.c 2003-10-14 04:09:34.000000000 -0400 -+++ src/linux/linux/net/ipv6/tcp_ipv6.c 2004-05-31 02:18:03.000000000 -0400 -@@ -1424,6 +1424,12 @@ - if (filter && sk_filter(skb, filter)) - goto discard; - #endif /* CONFIG_FILTER */ -+#ifdef CONFIG_NETSWAP -+ /* tcp doesn't use sock_queue_rcv_skb() ... */ -+ /* an inline function defined in net/netswapping.h */ -+ if (netswap_low_memory(sk, skb)) -+ goto discard; -+#endif /* CONFIG_NETSWAP */ - - /* - * socket locking is here for SMP purposes as backlog rcv -diff -Nurb src/linux/linux.orig/net/netswapping.c src/linux/linux/net/netswapping.c ---- src/linux/linux.orig/net/netswapping.c 1969-12-31 19:00:00.000000000 -0500 -+++ src/linux/linux/net/netswapping.c 2004-05-31 02:18:03.000000000 -0400 -@@ -0,0 +1,76 @@ -+/* -+ * linux/net/swapping.c -+ * -+ * Support paging over network connections (inet only) -+ * -+ * (c) 2000 Claus-Justus Heine -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+unsigned int netswap_dropped; /* statistics */ -+unsigned int netswap_free_pages_min; -+int netswap_sock_count; /* how many sockets have swapping option set */ -+ -+#ifdef CONFIG_SYSCTL -+ -+static ctl_table netswap_table[] = { -+ {NET_SWAP_DROPPED, "dropped", -+ &netswap_dropped, sizeof(int), 0644, NULL, &proc_dointvec }, -+ {NET_SWAP_DROP_THRESHOLD, "threshold", -+ &netswap_free_pages_min, sizeof(int), 0644, NULL, &proc_dointvec }, -+ {NET_SWAP_SOCK_COUNT, "sock_count", -+ &netswap_sock_count, sizeof(int), 0444, NULL, &proc_dointvec }, -+ {0}, -+}; -+ -+static struct ctl_table_header *netswap_sysctl_header; -+ -+static ctl_table netswap_net_table[] = { -+ {CTL_NETSWAP, "swapping", NULL, 0, 0555, netswap_table}, -+ {0} -+}; -+ -+static ctl_table netswap_root_table[] = { -+ {CTL_NET, "net", NULL, 0, 0555, netswap_net_table}, -+ {0} -+}; -+ -+#endif -+ -+int __init netswap_init(void) -+{ -+ /* drop packets when below this threshold */ -+ netswap_free_pages_min = 32 /* freepages.min */; -+#ifdef CONFIG_SYSCTL -+ netswap_sysctl_header = register_sysctl_table(netswap_root_table, 0); -+#endif -+ return 0; -+} -+ -+void __exit netswap_exit(void) -+{ -+#ifdef CONFIG_SYSCTL -+ unregister_sysctl_table(netswap_sysctl_header); -+#endif -+} -+ -+/* linux/init.h -- VERY nice :-) -+ * -+ * On the other hand, we have no control over the order the initcalls -+ * are performed ... -+ * -+ * Actually, we are not compiled as module ... -+ */ -+ -+module_init(netswap_init) -+module_exit(netswap_exit) -diff -Nurb src/linux/linux.orig/net/netsyms.c src/linux/linux/net/netsyms.c ---- src/linux/linux.orig/net/netsyms.c 2004-05-31 02:02:49.000000000 -0400 -+++ src/linux/linux/net/netsyms.c 2004-05-31 02:18:03.000000000 -0400 -@@ -601,4 +601,10 @@ - EXPORT_SYMBOL(wireless_send_event); - #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ - -+#ifdef CONFIG_NETSWAP -+EXPORT_SYMBOL(netswap_sock_count); -+EXPORT_SYMBOL(netswap_free_pages_min); -+EXPORT_SYMBOL(netswap_dropped); -+#endif -+ - #endif /* CONFIG_NET */ -diff -Nurb src/linux/linux.orig/net/packet/af_packet.c src/linux/linux/net/packet/af_packet.c ---- src/linux/linux.orig/net/packet/af_packet.c 2003-10-14 04:09:35.000000000 -0400 -+++ src/linux/linux/net/packet/af_packet.c 2004-05-31 02:18:03.000000000 -0400 -@@ -449,6 +449,12 @@ - snaplen = res; - } - #endif /* CONFIG_FILTER */ -+#ifdef CONFIG_NETSWAP -+ /* packet doesn't use sock_queue_rcv_skb() ... */ -+ /* an inline function defined in net/netswapping.h */ -+ if (netswap_low_memory(sk, skb)) -+ goto drop_n_restore; -+#endif /* CONFIG_NETSWAP */ - - if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) - goto drop_n_acct; -@@ -496,7 +502,7 @@ - po->stats.tp_drops++; - spin_unlock(&sk->receive_queue.lock); - --#ifdef CONFIG_FILTER -+#if defined(CONFIG_FILTER) || defined(CONFIG_NETSWAP) - drop_n_restore: - #endif - if (skb_head != skb->data && skb_shared(skb)) { -@@ -557,6 +563,12 @@ - snaplen = res; - } - #endif -+#ifdef CONFIG_NETSWAP -+ /* packet doesn't use sock_queue_rcv_skb() ... */ -+ /* an inline function defined in net/netswapping.h */ -+ if (netswap_low_memory(sk, skb)) -+ goto drop_n_restore; -+#endif /* CONFIG_NETSWAP */ - - if (sk->type == SOCK_DGRAM) { - macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16; -diff -Nurb src/linux/linux.orig/net/sunrpc/sched.c src/linux/linux/net/sunrpc/sched.c ---- src/linux/linux.orig/net/sunrpc/sched.c 2003-07-04 04:12:33.000000000 -0400 -+++ src/linux/linux/net/sunrpc/sched.c 2004-05-31 02:18:03.000000000 -0400 -@@ -79,10 +79,11 @@ - */ - static spinlock_t rpc_sched_lock = SPIN_LOCK_UNLOCKED; - -+#if CONFIG_SWAP_VIA_NFS || CONFIG_SWAP_VIA_NFS_MODULE - /* - * This is the last-ditch buffer for NFS swap requests - */ --static u32 swap_buffer[PAGE_SIZE >> 2]; -+static u32 swap_buffer[2*PAGE_SIZE >> 2]; - static long swap_buffer_used; - - /* -@@ -96,6 +97,7 @@ - { - clear_bit(1, &swap_buffer_used); - } -+#endif - - /* - * Disable the timer for a given RPC task. Should be called with -@@ -501,6 +503,7 @@ - __rpc_execute(struct rpc_task *task) - { - int status = 0; -+ unsigned long alloc_flag = current->flags & PF_MEMALLOC; - - dprintk("RPC: %4d rpc_execute flgs %x\n", - task->tk_pid, task->tk_flags); -@@ -510,6 +513,13 @@ - return 0; - } - -+ if (task->tk_flags & RPC_TASK_SWAPPER) { -+ if (!current->flags & PF_MEMALLOC) { -+ dprintk("__rpc_execute: Setting PF_MEMALLOC\n"); -+ } -+ current->flags |= PF_MEMALLOC; -+ } -+ - restarted: - while (1) { - /* -@@ -554,7 +564,8 @@ - rpc_set_sleeping(task); - if (RPC_IS_ASYNC(task)) { - spin_unlock_bh(&rpc_queue_lock); -- return 0; -+ status = 0; -+ goto out; - } - } - spin_unlock_bh(&rpc_queue_lock); -@@ -563,7 +574,12 @@ - /* sync task: sleep here */ - dprintk("RPC: %4d sync task going to sleep\n", - task->tk_pid); -- if (current->pid == rpciod_pid) -+ /* it's ok to wait for rpciod when swapping, -+ * because this means it needed memory and is -+ * doing the swap-out itself. -+ */ -+ if (current->pid == rpciod_pid && -+ !(task->tk_flags & RPC_TASK_SWAPPER)) - printk(KERN_ERR "RPC: rpciod waiting on sync task!\n"); - - __wait_event(task->tk_wait, !RPC_IS_SLEEPING(task)); -@@ -608,6 +624,10 @@ - /* Release all resources associated with the task */ - rpc_release_task(task); - -+ out: -+ if (!alloc_flag) { -+ current->flags &= ~PF_MEMALLOC; -+ } - return status; - } - -@@ -699,10 +719,16 @@ - { - u32 *buffer; - int gfp; -+ unsigned long alloc_flag = current->flags & PF_MEMALLOC; -+ void *ret = NULL; - -- if (flags & RPC_TASK_SWAPPER) -+ if (flags & RPC_TASK_SWAPPER) { - gfp = GFP_ATOMIC; -- else if (flags & RPC_TASK_ASYNC) -+ if (!(current->flags & PF_MEMALLOC)) { -+ dprintk("rpc_allocate: Setting PF_MEMALLOC\n"); -+ } -+ current->flags |= PF_MEMALLOC; -+ } else if (flags & RPC_TASK_ASYNC) - gfp = GFP_RPC; - else - gfp = GFP_KERNEL; -@@ -710,29 +736,44 @@ - do { - if ((buffer = (u32 *) kmalloc(size, gfp)) != NULL) { - dprintk("RPC: allocated buffer %p\n", buffer); -- return buffer; -+ ret = buffer; -+ goto out; - } -+#if CONFIG_SWAP_VIA_NFS || CONFIG_SWAP_VIA_NFS_MODULE - if ((flags & RPC_TASK_SWAPPER) && size <= sizeof(swap_buffer) - && rpc_lock_swapbuf()) { - dprintk("RPC: used last-ditch swap buffer\n"); -- return swap_buffer; -+ ret = swap_buffer; -+ goto out; -+#endif -+ } -+ if (flags & RPC_TASK_ASYNC) { -+ ret = NULL; -+ goto out; - } -- if (flags & RPC_TASK_ASYNC) -- return NULL; - yield(); - } while (!signalled()); - -- return NULL; -+ out: -+ if (!alloc_flag) { -+ current->flags &= ~PF_MEMALLOC; -+ } -+ return ret; - } - - void - rpc_free(void *buffer) - { -+#if CONFIG_SWAP_VIA_NFS || CONFIG_SWAP_VIA_NFS_MODULE - if (buffer != swap_buffer) { -+#endif - kfree(buffer); - return; -+#if CONFIG_SWAP_VIA_NFS || CONFIG_SWAP_VIA_NFS_MODULE - } - rpc_unlock_swapbuf(); -+ printk("RPC: Released swap buffer\n"); -+#endif - } - - /* -diff -Nurb src/linux/linux.orig/net/sunrpc/xprt.c src/linux/linux/net/sunrpc/xprt.c ---- src/linux/linux.orig/net/sunrpc/xprt.c 2003-07-04 04:12:33.000000000 -0400 -+++ src/linux/linux/net/sunrpc/xprt.c 2004-05-31 02:18:03.000000000 -0400 -@@ -139,7 +139,7 @@ - __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task) - { - if (!xprt->snd_task) { -- if (xprt->nocong || __xprt_get_cong(xprt, task)) -+ if (__xprt_get_cong(xprt, task)) - xprt->snd_task = task; - } - if (xprt->snd_task != task) { -@@ -179,7 +179,7 @@ - if (!task) - return; - } -- if (xprt->nocong || __xprt_get_cong(xprt, task)) -+ if (__xprt_get_cong(xprt, task)) - xprt->snd_task = task; - } - -@@ -276,6 +276,9 @@ - { - struct rpc_rqst *req = task->tk_rqstp; - -+ if (xprt->nocong || RPC_IS_SWAPPER(task)) -+ return 1; -+ - if (req->rq_cong) - return 1; - dprintk("RPC: %4d xprt_cwnd_limited cong = %ld cwnd = %ld\n", diff --git a/obsolete-buildroot/sources/openwrt-wrt54g-router.patch b/obsolete-buildroot/sources/openwrt-wrt54g-router.patch deleted file mode 100644 index 4098f792e2..0000000000 --- a/obsolete-buildroot/sources/openwrt-wrt54g-router.patch +++ /dev/null @@ -1,240 +0,0 @@ -diff -bBurN WRT54G/release/src/router/rc/Makefile-openwrt WRT54G.new/release/src/router/rc/Makefile-openwrt ---- WRT54G/release/src/router/rc/Makefile-openwrt 1969-12-31 18:00:00.000000000 -0600 -+++ WRT54G.new/release/src/router/rc/Makefile-openwrt 2004-03-03 16:23:40.000000000 -0600 -@@ -0,0 +1,44 @@ -+# Copyright 2001-2003, Broadcom Corporation -+# All Rights Reserved. -+# -+# -+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE -+# -+ -+# -+# Router Wireless Interface Configuration Utility Makefile -+# -+# Copyright 2003, Broadcom Corporation -+# All Rights Reserved. -+# -+# -+# $Id: Makefile,v 1.2 2004/01/13 00:55:58 mbm Exp $ -+# -+ -+CFLAGS += -I. -I$(TOP)/shared -I$(SRCBASE)/include -Wall -+#CFLAGS += -g -DDEBUG -+CFLAGS += -s -Os -+LDFLAGS += -L$(TOP)/shared -lshared -L$(TOP)/nvram -lnvram -+ -+OBJS := mtd.o crc.o #http.o -+ -+vpath %.c $(TOP)/shared $(SRCBASE)/rts/src -+ -+all: mtd -+ -+clean: -+ rm -f *.o mtd -+ -+install: all -+ install -d $(INSTALLDIR)/sbin -+ install mtd $(INSTALLDIR)/sbin -+ $(STRIP) $(INSTALLDIR)/sbin/mtd -+ -+mtd.o: mtd.c -+ $(CC) -c $^ $(CFLAGS) $(CPPFLAGS) -DOPENWRT_MTD #-DOPENWRT_MTD_HTTP_GET -+ -+mtd: $(OBJS) -+ $(CC) -o $@ $^ $(LDFLAGS) -diff -bBurN WRT54G/release/src/router/rc/mtd.c WRT54G.new/release/src/router/rc/mtd.c ---- WRT54G/release/src/router/rc/mtd.c 2004-01-19 20:34:50.000000000 -0600 -+++ WRT54G.new/release/src/router/rc/mtd.c 2004-03-03 16:24:42.000000000 -0600 -@@ -37,6 +37,86 @@ - #include - #include - -+ -+#ifdef OPENWRT_MTD -+ -+extern int -+mtd_open(const char *mtd, int flags); -+extern int -+mtd_erase(const char *mtd); -+extern int -+mtd_write(const char *path, const char *mtd); -+ -+/* Slightly modified version of mtd_erase. */ -+int -+mtd_unlock(const char *mtd) -+{ -+ int mtd_fd; -+ mtd_info_t mtd_info; -+ erase_info_t erase_info; -+ -+ /* Open MTD device */ -+ if ((mtd_fd = mtd_open(mtd, O_RDWR)) < 0) { -+ perror(mtd); -+ return errno; -+ } -+ -+ /* Get sector size */ -+ if (ioctl(mtd_fd, MEMGETINFO, &mtd_info) != 0) { -+ perror(mtd); -+ close(mtd_fd); -+ return errno; -+ } -+ -+ erase_info.length = mtd_info.erasesize; -+ -+ for (erase_info.start = 0; -+ erase_info.start < mtd_info.size; -+ erase_info.start += mtd_info.erasesize) { -+ (void) ioctl(mtd_fd, MEMUNLOCK, &erase_info); -+/* if (ioctl(mtd_fd, MEMERASE, &erase_info) != 0) { */ -+/* perror(mtd); */ -+/* close(mtd_fd); */ -+/* return errno; */ -+/* } */ -+ } -+ -+ close(mtd_fd); -+ return 0; -+} -+ -+int main(int argc, char **argv) { -+ if(argc == 3 && strcasecmp(argv[1],"unlock")==0) { -+ printf("Unlocking %s\n",argv[2]); -+ return mtd_unlock(argv[2]); -+ } -+ if(argc == 3 && strcasecmp(argv[1],"erase")==0) { -+ printf("Erasing %s\n",argv[2]); -+ return mtd_erase(argv[2]); -+ } -+ if(argc == 4 && strcasecmp(argv[1],"write")==0) { -+ printf("writing %s to %s\n",argv[2],argv[3]); -+ return mtd_write(argv[2],argv[3]); -+ } -+ -+ printf("no valid command given\n"); -+ return -1; -+} -+ -+#ifndef OPENWRT_MTD_HTTP_GET -+/* Dummy routines when no http support. */ -+int -+http_get(const char *server, char *buf, size_t count, off_t offset) -+{ -+ printf("error opening %s\n",server); -+ exit(-1); -+} -+#endif -+ -+#define check_action() (fp ? ACT_IDLE : ACT_WEBS_UPGRADE) -+ -+#endif -+ - /* - * Open an MTD device - * @param mtd path to or partition name of MTD device -diff -bBurN WRT54G/release/src/router/shared/Makefile-openwrt WRT54G.new/release/src/router/shared/Makefile-openwrt ---- WRT54G/release/src/router/shared/Makefile-openwrt 1969-12-31 18:00:00.000000000 -0600 -+++ WRT54G.new/release/src/router/shared/Makefile-openwrt 2004-03-03 12:39:17.000000000 -0600 -@@ -0,0 +1,41 @@ -+# -+# Linux router shared code Makefile -+# -+# Copyright 2001-2003, Broadcom Corporation -+# All Rights Reserved. -+# -+# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY -+# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM -+# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS -+# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. -+# -+# $Id: Makefile,v 1.3 2004/01/13 00:51:09 mbm Exp $ -+# -+ifneq ($(wildcard $(SRCBASE)/cy_conf.mak),) -+ include $(SRCBASE)/cy_conf.mak -+endif -+ -+CFLAGS += -I. -I$(SRCBASE)/include -Wall -I$(SRCBASE)/ -+#CFLAGS += -g -DDEBUG -+CFLAGS += -s -Os -+LDFLAGS += -L. -+ -+all: libshared.so -+ -+install: all -+ install -d $(INSTALLDIR)/usr/lib -+ install -m 755 libshared.so $(INSTALLDIR)/usr/lib -+ $(STRIP) $(INSTALLDIR)/usr/lib/libshared.so -+ -+clean: -+ rm -f *.o *.so -+ -+libshared.so: shutils.o wl.o wl_linux.o defaults.o -+ $(LD) -shared -o $@ $^ -+ -+build_date.o: build_date.c -+ -+build_date: -+ echo "const char *builddate = \"`date`\";" > build_date.c -+ -+*.o: $(CY_DEPS) -diff -bBurN WRT54GS/release/src/router/nvram/nvram_linux.c-dist WRT54GS.new/release/src/router/nvram/nvram_linux.c ---- WRT54GS/release/src/router/nvram/nvram_linux.c-dist 2004-03-30 10:04:10.000000000 -0600 -+++ WRT54GS/release/src/router/nvram/nvram_linux.c 2004-03-30 10:10:09.000000000 -0600 -@@ -27,8 +27,10 @@ - #include - #include - #include -+#ifndef OPENWRT_NVRAM - #include - #include -+#endif - - #define PATH_DEV_NVRAM "/dev/nvram" - -@@ -182,6 +184,20 @@ - { - int ret; - -+#ifdef OPENWRT_NVRAM -+ fprintf(stderr, "nvram_commit(): start\n"); -+ -+ if (nvram_fd < 0) -+ if ((ret = nvram_init(NULL))) -+ return ret; -+ -+ ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL); -+ -+ if (ret < 0) -+ perror(PATH_DEV_NVRAM); -+ -+ fprintf(stderr, "nvram_commit(): end\n"); -+#else - cprintf("nvram_commit(): start\n"); - - if((check_action() == ACT_IDLE) || -@@ -200,6 +216,7 @@ - } - else - cprintf("nvram_commit(): nothing to do...\n"); -+#endif - - return ret; - } -@@ -272,6 +289,7 @@ - return j; - } - -+#ifndef OPENWRT_NVRAM - int - check_action(void) - { -@@ -318,3 +336,5 @@ - - return 0; - } -+ -+#endif diff --git a/obsolete-buildroot/sources/openwrt-wrt54g-shared.patch b/obsolete-buildroot/sources/openwrt-wrt54g-shared.patch deleted file mode 100644 index f357885bcc..0000000000 --- a/obsolete-buildroot/sources/openwrt-wrt54g-shared.patch +++ /dev/null @@ -1,11 +0,0 @@ ---- WRT54G/release/src/shared/sbpci.c-dist 2004-03-15 13:13:37.000000000 -0600 -+++ WRT54G/release/src/shared/sbpci.c 2004-03-15 13:15:38.000000000 -0600 -@@ -269,7 +269,7 @@ - sb_core_reset(sbh, 0); - - /* In some board, */ -- if(nvram_match("boardtype", "bcm94710dev")) -+ if(nvram_match("boardtype", "bcm94710dev") || nvram_match("boardtype", "bcm94710ap")) - CT4712_WR = 0; - else - CT4712_WR = 1; diff --git a/obsolete-buildroot/sources/openwrt/busybox/busybox.config b/obsolete-buildroot/sources/openwrt/busybox/busybox.config new file mode 100644 index 0000000000..2d7c51fb34 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/busybox/busybox.config @@ -0,0 +1,459 @@ +# +# Automatically generated make config: don't edit +# +HAVE_DOT_CONFIG=y + +# +# General Configuration +# +# CONFIG_FEATURE_BUFFERS_USE_MALLOC is not set +CONFIG_FEATURE_BUFFERS_GO_ON_STACK=y +# CONFIG_FEATURE_BUFFERS_GO_IN_BSS is not set +CONFIG_FEATURE_VERBOSE_USAGE=y +# CONFIG_FEATURE_INSTALLER is not set +# CONFIG_LOCALE_SUPPORT is not set +CONFIG_FEATURE_DEVFS=y +CONFIG_FEATURE_DEVPTS=y +# CONFIG_FEATURE_CLEAN_UP is not set +# CONFIG_FEATURE_SUID is not set +# CONFIG_SELINUX is not set + +# +# Build Options +# +# CONFIG_STATIC is not set +CONFIG_LFS=y +USING_CROSS_COMPILER=y +CROSS_COMPILER_PREFIX="mipsel-uclibc-" +EXTRA_CFLAGS_OPTIONS="-Os " + +# +# Installation Options +# +# CONFIG_INSTALL_NO_USR is not set +PREFIX="./_install" + +# +# Archival Utilities +# +# CONFIG_AR is not set +CONFIG_BUNZIP2=y +# CONFIG_CPIO is not set +# CONFIG_DPKG is not set +# CONFIG_DPKG_DEB is not set +CONFIG_GUNZIP=y +CONFIG_FEATURE_GUNZIP_UNCOMPRESS=y +CONFIG_GZIP=y +# CONFIG_RPM2CPIO is not set +# CONFIG_RPM is not set +CONFIG_TAR=y +CONFIG_FEATURE_TAR_CREATE=y +CONFIG_FEATURE_TAR_BZIP2=y +# CONFIG_FEATURE_TAR_FROM is not set +CONFIG_FEATURE_TAR_GZIP=y +# CONFIG_FEATURE_TAR_COMPRESS is not set +# CONFIG_FEATURE_TAR_OLDGNU_COMPATABILITY is not set +CONFIG_FEATURE_TAR_GNU_EXTENSIONS=y +# CONFIG_FEATURE_TAR_LONG_OPTIONS is not set +# CONFIG_UNCOMPRESS is not set +# CONFIG_UNZIP is not set + +# +# Common options for cpio and tar +# +# CONFIG_FEATURE_UNARCHIVE_TAPE is not set + +# +# Coreutils +# +CONFIG_BASENAME=y +# CONFIG_CAL is not set +CONFIG_CAT=y +CONFIG_CHGRP=y +CONFIG_CHMOD=y +CONFIG_CHOWN=y +CONFIG_CHROOT=y +# CONFIG_CMP is not set +CONFIG_CP=y +CONFIG_CUT=y +CONFIG_DATE=y +CONFIG_FEATURE_DATE_ISOFMT=y +CONFIG_DD=y +CONFIG_DF=y +# CONFIG_DIRNAME is not set +# CONFIG_DOS2UNIX is not set +# CONFIG_DU is not set +CONFIG_ECHO=y +CONFIG_FEATURE_FANCY_ECHO=y +CONFIG_ENV=y +CONFIG_EXPR=y +CONFIG_FALSE=y +# CONFIG_FOLD is not set +CONFIG_HEAD=y +# CONFIG_FEATURE_FANCY_HEAD is not set +CONFIG_HOSTID=y +# CONFIG_ID is not set +CONFIG_INSTALL=y +CONFIG_LENGTH=y +CONFIG_LN=y +# CONFIG_LOGNAME is not set +CONFIG_LS=y +CONFIG_FEATURE_LS_FILETYPES=y +CONFIG_FEATURE_LS_FOLLOWLINKS=y +CONFIG_FEATURE_LS_RECURSIVE=y +CONFIG_FEATURE_LS_SORTFILES=y +CONFIG_FEATURE_LS_TIMESTAMPS=y +CONFIG_FEATURE_LS_USERNAME=y +CONFIG_FEATURE_LS_COLOR=y +CONFIG_MD5SUM=y +CONFIG_MKDIR=y +CONFIG_MKFIFO=y +# CONFIG_MKNOD is not set +CONFIG_MV=y +# CONFIG_OD is not set +# CONFIG_PRINTF is not set +CONFIG_PWD=y +# CONFIG_REALPATH is not set +CONFIG_RM=y +CONFIG_RMDIR=y +# CONFIG_SEQ is not set +# CONFIG_SHA1SUM is not set +CONFIG_SLEEP=y +CONFIG_FEATURE_FANCY_SLEEP=y +CONFIG_SORT=y +# CONFIG_STTY is not set +CONFIG_SYNC=y +CONFIG_TAIL=y +CONFIG_FEATURE_FANCY_TAIL=y +CONFIG_TEE=y +CONFIG_FEATURE_TEE_USE_BLOCK_IO=y +CONFIG_TEST=y + +# +# test (forced enabled for use with shell) +# +CONFIG_TOUCH=y +# CONFIG_TR is not set +CONFIG_TRUE=y +# CONFIG_TTY is not set +CONFIG_UNAME=y +CONFIG_UNIQ=y +# CONFIG_USLEEP is not set +# CONFIG_UUDECODE is not set +# CONFIG_UUENCODE is not set +# CONFIG_WATCH is not set +CONFIG_WC=y +# CONFIG_WHO is not set +# CONFIG_WHOAMI is not set +CONFIG_YES=y + +# +# Common options for cp and mv +# +CONFIG_FEATURE_PRESERVE_HARDLINKS=y + +# +# Common options for ls and more +# +CONFIG_FEATURE_AUTOWIDTH=y + +# +# Common options for df, du, ls +# +CONFIG_FEATURE_HUMAN_READABLE=y + +# +# Common options for md5sum, sha1sum +# +CONFIG_FEATURE_MD5_SHA1_SUM_CHECK=y + +# +# Console Utilities +# +# CONFIG_CHVT is not set +CONFIG_CLEAR=y +# CONFIG_DEALLOCVT is not set +# CONFIG_DUMPKMAP is not set +# CONFIG_LOADFONT is not set +# CONFIG_LOADKMAP is not set +# CONFIG_OPENVT is not set +CONFIG_RESET=y +# CONFIG_SETKEYCODES is not set + +# +# Debian Utilities +# +CONFIG_MKTEMP=y +# CONFIG_PIPE_PROGRESS is not set +# CONFIG_READLINK is not set +CONFIG_RUN_PARTS=y +# CONFIG_START_STOP_DAEMON is not set +CONFIG_WHICH=y + +# +# Editors +# +CONFIG_AWK=y +CONFIG_FEATURE_AWK_MATH=y +# CONFIG_PATCH is not set +CONFIG_SED=y +CONFIG_VI=y +CONFIG_FEATURE_VI_COLON=y +CONFIG_FEATURE_VI_YANKMARK=y +CONFIG_FEATURE_VI_SEARCH=y +CONFIG_FEATURE_VI_USE_SIGNALS=y +CONFIG_FEATURE_VI_DOT_CMD=y +CONFIG_FEATURE_VI_READONLY=y +CONFIG_FEATURE_VI_SETOPTS=y +CONFIG_FEATURE_VI_SET=y +CONFIG_FEATURE_VI_WIN_RESIZE=y +CONFIG_FEATURE_VI_OPTIMIZE_CURSOR=y + +# +# Finding Utilities +# +CONFIG_FIND=y +# CONFIG_FEATURE_FIND_MTIME is not set +CONFIG_FEATURE_FIND_PERM=y +CONFIG_FEATURE_FIND_TYPE=y +CONFIG_FEATURE_FIND_XDEV=y +# CONFIG_FEATURE_FIND_NEWER is not set +# CONFIG_FEATURE_FIND_INUM is not set +CONFIG_GREP=y +CONFIG_FEATURE_GREP_EGREP_ALIAS=y +CONFIG_FEATURE_GREP_FGREP_ALIAS=y +CONFIG_FEATURE_GREP_CONTEXT=y +CONFIG_XARGS=y +CONFIG_FEATURE_XARGS_SUPPORT_CONFIRMATION=y +CONFIG_FEATURE_XARGS_SUPPORT_QUOTES=y +CONFIG_FEATURE_XARGS_SUPPORT_TERMOPT=y +CONFIG_FEATURE_XARGS_SUPPORT_ZERO_TERM=y + +# +# Init Utilities +# +CONFIG_INIT=y +CONFIG_FEATURE_USE_INITTAB=y +# CONFIG_FEATURE_INITRD is not set +# CONFIG_FEATURE_INIT_COREDUMPS is not set +# CONFIG_FEATURE_EXTRA_QUIET is not set +# CONFIG_HALT is not set +# CONFIG_POWEROFF is not set +CONFIG_REBOOT=y +CONFIG_MESG=y + +# +# Login/Password Management Utilities +# +# CONFIG_USE_BB_PWD_GRP is not set +# CONFIG_ADDGROUP is not set +# CONFIG_DELGROUP is not set +# CONFIG_ADDUSER is not set +# CONFIG_DELUSER is not set +# CONFIG_GETTY is not set +# CONFIG_LOGIN is not set +CONFIG_PASSWD=y +# CONFIG_SU is not set +# CONFIG_SULOGIN is not set +# CONFIG_VLOCK is not set + +# +# Miscellaneous Utilities +# +# CONFIG_ADJTIMEX is not set +CONFIG_CROND=y +# CONFIG_FEATURE_CROND_CALL_SENDMAIL is not set +CONFIG_CRONTAB=y +# CONFIG_DC is not set +# CONFIG_DEVFSD is not set +# CONFIG_LAST is not set +# CONFIG_HDPARM is not set +# CONFIG_MAKEDEVS is not set +# CONFIG_MT is not set +CONFIG_RESETMON=y +# CONFIG_RX is not set +CONFIG_STRINGS=y +CONFIG_TIME=y +# CONFIG_WATCHDOG is not set + +# +# Linux Module Utilities +# +CONFIG_INSMOD=y +CONFIG_FEATURE_2_4_MODULES=y +# CONFIG_FEATURE_2_6_MODULES is not set +# CONFIG_FEATURE_INSMOD_VERSION_CHECKING is not set +# CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS is not set +# CONFIG_FEATURE_INSMOD_LOADINKMEM is not set +# CONFIG_FEATURE_INSMOD_LOAD_MAP is not set +CONFIG_LSMOD=y +CONFIG_FEATURE_QUERY_MODULE_INTERFACE=y +# CONFIG_MODPROBE is not set +CONFIG_RMMOD=y +# CONFIG_FEATURE_CHECK_TAINTED_MODULE is not set + +# +# Networking Utilities +# +CONFIG_FEATURE_IPV6=y +CONFIG_ARPING=y +# CONFIG_FTPGET is not set +# CONFIG_FTPPUT is not set +# CONFIG_HOSTNAME is not set +CONFIG_HTTPD=y +# CONFIG_FEATURE_HTTPD_USAGE_FROM_INETD_ONLY is not set +CONFIG_FEATURE_HTTPD_BASIC_AUTH=y +CONFIG_FEATURE_HTTPD_AUTH_MD5=y +CONFIG_FEATURE_HTTPD_RELOAD_CONFIG_SIGHUP=y +# CONFIG_FEATURE_HTTPD_SETUID is not set +CONFIG_FEATURE_HTTPD_CONFIG_WITH_MIME_TYPES=y +CONFIG_FEATURE_HTTPD_CGI=y +CONFIG_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV=y +CONFIG_FEATURE_HTTPD_ENCODE_URL_STR=y +CONFIG_IFCONFIG=y +CONFIG_FEATURE_IFCONFIG_STATUS=y +# CONFIG_FEATURE_IFCONFIG_SLIP is not set +# CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ is not set +CONFIG_FEATURE_IFCONFIG_HW=y +CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS=y +# CONFIG_IFUPDOWN is not set +# CONFIG_INETD is not set +# CONFIG_IP is not set +CONFIG_IPCALC=y +CONFIG_FEATURE_IPCALC_FANCY=y +# CONFIG_IPADDR is not set +# CONFIG_IPLINK is not set +# CONFIG_IPROUTE is not set +# CONFIG_IPTUNNEL is not set +# CONFIG_NAMEIF is not set +CONFIG_NC=y +CONFIG_NETSTAT=y +CONFIG_NSLOOKUP=y +CONFIG_PING=y +CONFIG_FEATURE_FANCY_PING=y +CONFIG_PING6=y +CONFIG_FEATURE_FANCY_PING6=y +CONFIG_ROUTE=y +# CONFIG_TELNET is not set +CONFIG_TELNETD=y +# CONFIG_FEATURE_TELNETD_INETD is not set +# CONFIG_TFTP is not set +CONFIG_TRACEROUTE=y +CONFIG_FEATURE_TRACEROUTE_VERBOSE=y +CONFIG_VCONFIG=y +CONFIG_WGET=y +CONFIG_FEATURE_WGET_STATUSBAR=y +CONFIG_FEATURE_WGET_AUTHENTICATION=y +CONFIG_FEATURE_WGET_IP6_LITERAL=y + +# +# udhcp Server/Client +# +# CONFIG_UDHCPD is not set +CONFIG_UDHCPC=y +# CONFIG_FEATURE_UDHCP_SYSLOG is not set +# CONFIG_FEATURE_UDHCP_DEBUG is not set + +# +# Process Utilities +# +CONFIG_FREE=y +CONFIG_KILL=y +CONFIG_KILLALL=y +CONFIG_KILLALL5=y +CONFIG_PIDOF=y +CONFIG_PS=y +# CONFIG_RENICE is not set +CONFIG_TOP=y +FEATURE_CPU_USAGE_PERCENTAGE=y +CONFIG_UPTIME=y +CONFIG_SYSCTL=y + +# +# Another Bourne-like Shell +# +CONFIG_FEATURE_SH_IS_ASH=y +# CONFIG_FEATURE_SH_IS_HUSH is not set +# CONFIG_FEATURE_SH_IS_LASH is not set +# CONFIG_FEATURE_SH_IS_MSH is not set +# CONFIG_FEATURE_SH_IS_NONE is not set +CONFIG_ASH=y + +# +# Ash Shell Options +# +CONFIG_ASH_JOB_CONTROL=y +CONFIG_ASH_ALIAS=y +CONFIG_ASH_MATH_SUPPORT=y +# CONFIG_ASH_MATH_SUPPORT_64 is not set +CONFIG_ASH_GETOPTS=y +CONFIG_ASH_CMDCMD=y +# CONFIG_ASH_MAIL is not set +CONFIG_ASH_OPTIMIZE_FOR_SIZE=y +# CONFIG_ASH_RANDOM_SUPPORT is not set +# CONFIG_HUSH is not set +# CONFIG_LASH is not set +# CONFIG_MSH is not set + +# +# Bourne Shell Options +# +# CONFIG_FEATURE_SH_EXTRA_QUIET is not set +# CONFIG_FEATURE_SH_STANDALONE_SHELL is not set +CONFIG_FEATURE_COMMAND_EDITING=y +CONFIG_FEATURE_COMMAND_HISTORY=15 +# CONFIG_FEATURE_COMMAND_SAVEHISTORY is not set +CONFIG_FEATURE_COMMAND_TAB_COMPLETION=y +# CONFIG_FEATURE_COMMAND_USERNAME_COMPLETION is not set +CONFIG_FEATURE_SH_FANCY_PROMPT=y + +# +# System Logging Utilities +# +CONFIG_SYSLOGD=y +CONFIG_FEATURE_ROTATE_LOGFILE=y +CONFIG_FEATURE_REMOTE_LOG=y +CONFIG_FEATURE_IPC_SYSLOG=y +CONFIG_FEATURE_IPC_SYSLOG_BUFFER_SIZE=16 +CONFIG_LOGREAD=y +# CONFIG_FEATURE_LOGREAD_REDUCED_LOCKING is not set +CONFIG_KLOGD=y +CONFIG_LOGGER=y + +# +# Linux System Utilities +# +CONFIG_DMESG=y +# CONFIG_FBSET is not set +# CONFIG_FDFLUSH is not set +# CONFIG_FDFORMAT is not set +# CONFIG_FDISK is not set +FDISK_SUPPORT_LARGE_DISKS=y +# CONFIG_FREERAMDISK is not set +# CONFIG_FSCK_MINIX is not set +# CONFIG_MKFS_MINIX is not set +# CONFIG_GETOPT is not set +CONFIG_HEXDUMP=y +# CONFIG_HWCLOCK is not set +# CONFIG_LOSETUP is not set +# CONFIG_MKSWAP is not set +CONFIG_MORE=y +CONFIG_FEATURE_USE_TERMIOS=y +CONFIG_PIVOT_ROOT=y +CONFIG_RDATE=y +# CONFIG_SWAPONOFF is not set +CONFIG_MOUNT=y +CONFIG_NFSMOUNT=y +CONFIG_UMOUNT=y +CONFIG_FEATURE_MOUNT_FORCE=y + +# +# Common options for mount/umount +# +CONFIG_FEATURE_MOUNT_LOOP=y +# CONFIG_FEATURE_MTAB_SUPPORT is not set + +# +# Debugging Options +# +# CONFIG_DEBUG is not set diff --git a/obsolete-buildroot/sources/openwrt/busybox/patches/100-killall5.patch b/obsolete-buildroot/sources/openwrt/busybox/patches/100-killall5.patch new file mode 100644 index 0000000000..161b7e6f25 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/busybox/patches/100-killall5.patch @@ -0,0 +1,87 @@ +diff -urN busybox-dist/include/applets.h busybox/include/applets.h +--- busybox-dist/include/applets.h 2004-03-13 02:33:09.000000000 -0600 ++++ busybox/include/applets.h 2004-03-16 09:45:29.000000000 -0600 +@@ -313,6 +313,9 @@ + #ifdef CONFIG_KILLALL + APPLET(killall, kill_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) + #endif ++#ifdef CONFIG_KILLALL5 ++ APPLET(killall5, kill_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) ++#endif + #ifdef CONFIG_KLOGD + APPLET(klogd, klogd_main, _BB_DIR_SBIN, _BB_SUID_NEVER) + #endif +diff -urN busybox-dist/include/usage.h busybox/include/usage.h +--- busybox-dist/include/usage.h 2004-03-13 02:33:09.000000000 -0600 ++++ busybox/include/usage.h 2004-03-16 09:45:29.000000000 -0600 +@@ -1389,6 +1389,13 @@ + #define killall_example_usage \ + "$ killall apache\n" + ++#define killall5_trivial_usage \ ++ "" ++#define killall5_full_usage \ ++ "" ++#define killall5_example_usage \ ++ "" ++ + #define klogd_trivial_usage \ + "[-c n] [-n]" + #define klogd_full_usage \ +diff -urN busybox-dist/procps/Config.in busybox/procps/Config.in +--- busybox-dist/procps/Config.in 2003-12-24 00:02:11.000000000 -0600 ++++ busybox/procps/Config.in 2004-03-16 09:45:29.000000000 -0600 +@@ -30,6 +30,11 @@ + specified commands. If no signal name is specified, SIGTERM is + sent. + ++config CONFIG_KILLALL5 ++ bool "killall5" ++ default n ++ depends on CONFIG_KILL ++ + config CONFIG_PIDOF + bool "pidof" + default n +diff -urN busybox-dist/procps/kill.c busybox/procps/kill.c +--- busybox-dist/procps/kill.c 2004-03-15 02:29:03.000000000 -0600 ++++ busybox/procps/kill.c 2004-03-16 09:45:29.000000000 -0600 +@@ -34,6 +34,7 @@ + + #define KILL 0 + #define KILLALL 1 ++#define KILLALL5 2 + + extern int kill_main(int argc, char **argv) + { +@@ -47,6 +48,9 @@ + #else + whichApp = KILL; + #endif ++#ifdef CONFIG_KILLALL5 ++ whichApp = (strcmp(bb_applet_name, "killall5") == 0)? KILLALL5 : whichApp; ++#endif + + /* Parse any options */ + if (argc < 2) +@@ -119,6 +123,20 @@ + } + + } ++#ifdef CONFIG_KILLALL5 ++ else if (whichApp == KILLALL5) { ++ procps_status_t * p; ++ pid_t myPid=getpid(); ++ while ((p = procps_scan(0)) != 0) { ++ if (p->pid != 1 && p->pid != myPid && p->pid != p->ppid) { ++ if (kill(p->pid, signo) != 0) { ++ bb_perror_msg( "Could not kill pid '%d'", p->pid); ++ errors++; ++ } ++ } ++ } ++ } ++#endif + #ifdef CONFIG_KILLALL + else { + pid_t myPid=getpid(); diff --git a/obsolete-buildroot/sources/openwrt/busybox/patches/110-telnetd.patch b/obsolete-buildroot/sources/openwrt/busybox/patches/110-telnetd.patch new file mode 100644 index 0000000000..e95757ee4e --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/busybox/patches/110-telnetd.patch @@ -0,0 +1,53 @@ +diff -urN busybox-1.00-pre8/networking/telnetd.c busybox-1.00-pre8-openwrt/networking/telnetd.c +--- busybox-1.00-pre8/networking/telnetd.c 2004-02-22 03:45:57.000000000 -0600 ++++ busybox-1.00-pre8-openwrt/networking/telnetd.c 2004-03-05 01:32:57.000000000 -0600 +@@ -44,6 +44,8 @@ + #include + #include + #include ++#include ++ + + #include "busybox.h" + +@@ -384,11 +386,13 @@ + int portnbr = 23; + #endif /* CONFIG_FEATURE_TELNETD_INETD */ + int c; ++ char *interface_name = NULL; ++ struct ifreq interface; + static const char options[] = + #ifdef CONFIG_FEATURE_TELNETD_INETD +- "f:l:"; +-#else /* CONFIG_EATURE_TELNETD_INETD */ +- "f:l:p:"; ++ "i:f:l:"; ++#else /* CONFIG_FEATURE_TELNETD_INETD */ ++ "i:f:l:p:"; + #endif /* CONFIG_FEATURE_TELNETD_INETD */ + int maxlen, w, r; + +@@ -403,6 +407,9 @@ + case 'f': + issuefile = strdup (optarg); + break; ++ case 'i': ++ interface_name = strdup(optarg); ++ break; + case 'l': + loginpath = strdup (optarg); + break; +@@ -442,6 +449,13 @@ + sa.sin_family = AF_INET; + sa.sin_port = htons(portnbr); + ++ /* Set it to listen on the specified interface */ ++ if (interface_name) { ++ strncpy(interface.ifr_ifrn.ifrn_name, interface_name, IFNAMSIZ); ++ (void)setsockopt(master_fd, SOL_SOCKET, ++ SO_BINDTODEVICE, &interface, sizeof(interface)); ++ } ++ + if (bind(master_fd, (struct sockaddr *) &sa, sizeof(sa)) < 0) { + bb_perror_msg_and_die("bind"); + } diff --git a/obsolete-buildroot/sources/openwrt/busybox/patches/130-resetmon.patch b/obsolete-buildroot/sources/openwrt/busybox/patches/130-resetmon.patch new file mode 100644 index 0000000000..b41315e1f7 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/busybox/patches/130-resetmon.patch @@ -0,0 +1,89 @@ +diff -urN busybox-dist/include/applets.h busybox/include/applets.h +--- busybox-dist/include/applets.h 2004-03-16 09:56:27.000000000 -0600 ++++ busybox/include/applets.h 2004-03-16 10:00:14.000000000 -0600 +@@ -484,6 +484,9 @@ + #ifdef CONFIG_RESET + APPLET(reset, reset_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER) + #endif ++#ifdef CONFIG_RESETMON ++ APPLET(resetmon, resetmon_main, _BB_DIR_SBIN, _BB_SUID_NEVER) ++#endif + #ifdef CONFIG_RM + APPLET(rm, rm_main, _BB_DIR_BIN, _BB_SUID_NEVER) + #endif +diff -urN busybox-dist/include/usage.h busybox/include/usage.h +--- busybox-dist/include/usage.h 2004-03-16 09:56:27.000000000 -0600 ++++ busybox/include/usage.h 2004-03-16 10:00:14.000000000 -0600 +@@ -2024,6 +2024,11 @@ + #define reset_full_usage \ + "Resets the screen." + ++#define resetmon_trivial_usage \ ++ "" ++#define resetmon_full_usage \ ++ "Return an exit code of TRUE (0) if reset is NOT pressed." ++ + #define rm_trivial_usage \ + "[OPTION]... FILE..." + #define rm_full_usage \ +diff -urN busybox-dist/miscutils/Config.in busybox/miscutils/Config.in +--- busybox-dist/miscutils/Config.in 2004-03-15 02:28:46.000000000 -0600 ++++ busybox/miscutils/Config.in 2004-03-16 10:00:14.000000000 -0600 +@@ -156,6 +156,12 @@ + to advance or rewind a tape past a specified number of archive + files on the tape. + ++config CONFIG_RESETMON ++ bool "resetmon" ++ default y ++ help ++ Linksys wrt54g reset button monitor. Returns TRUE if NOT pressed. ++ + config CONFIG_RX + bool "rx" + default n +diff -urN busybox-dist/miscutils/Makefile.in busybox/miscutils/Makefile.in +--- busybox-dist/miscutils/Makefile.in 2004-03-15 02:28:46.000000000 -0600 ++++ busybox/miscutils/Makefile.in 2004-03-16 10:00:14.000000000 -0600 +@@ -33,6 +33,7 @@ + MISCUTILS-$(CONFIG_LAST) += last.o + MISCUTILS-$(CONFIG_MAKEDEVS) += makedevs.o + MISCUTILS-$(CONFIG_MT) += mt.o ++MISCUTILS-$(CONFIG_RESETMON) += resetmon.o + MISCUTILS-$(CONFIG_RX) += rx.o + MISCUTILS-$(CONFIG_STRINGS) += strings.o + MISCUTILS-$(CONFIG_TIME) += time.o +diff -urN busybox-dist/miscutils/resetmon.c busybox/miscutils/resetmon.c +--- busybox-dist/miscutils/resetmon.c 1969-12-31 18:00:00.000000000 -0600 ++++ busybox/miscutils/resetmon.c 2004-03-16 10:00:14.000000000 -0600 +@@ -0,0 +1,30 @@ ++#include ++#include ++#include "busybox.h" ++ ++#define RESET (1<<6) ++ ++int resetmon_main(int argc, char **argv) { ++ int fd = -1; ++ unsigned int val=0; ++ ++#if 0 ++ if ((fd = open("/dev/gpio/control",O_RDWR))<0) goto error; ++ read(fd,&val,4); ++ val|=RESET; ++ write(fd,&val,4); ++ ++ if ((fd = open("/dev/gpio/outen",O_RDWR))<0) goto error; ++ read(fd,&val,4); ++ val&=~RESET; ++ write(fd,&val,4); ++#endif ++ ++ if ((fd = open("/dev/gpio/in",O_RDONLY))<0) goto error; ++ read(fd,&val,4); ++ ++ return !(val&RESET); ++ ++error: ++ return 1; ++} diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.conffiles b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.conffiles new file mode 100644 index 0000000000..cb3c639ba6 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.conffiles @@ -0,0 +1 @@ +/etc/ssh_config diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.control b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.control new file mode 100644 index 0000000000..358525098c --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.control @@ -0,0 +1,12 @@ +Package: openssh-client +Priority: optional +Version: 3.8p1-1 +Architecture: mipsel +Maintainer: below0 +Section: net +Depends: zlib libssl +Source: Embedded in the main OpenWrt buildroot +Description: The OpenSSH client. Allows for access to remote systems via the SSH protocol. + Includes: ssh, scp + + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.ex.control b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.ex.control new file mode 100644 index 0000000000..5eb808a979 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.ex.control @@ -0,0 +1,12 @@ +Package: openssh-client-extras +Priority: optional +Version: 3.8p1-1 +Architecture: mipsel +Maintainer: below0 +Section: net +Depends: openssh-client +Source: Embedded in the main OpenWrt buildroot +Description: Various optional OpenSSH client tools. + Includes: ssh-add, ssh-agent, ssh-keyscan, ssk-keysign + + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.preinst b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.preinst new file mode 100644 index 0000000000..029c78978a --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.preinst @@ -0,0 +1,10 @@ +#!/bin/sh + +# Make sure password and group databases exist +if [ ! -f /etc/passwd ]; then + echo -e "root::0:0::/tmp:/bin/sh\nnobody:x:65534:65534:nobody:/tmp:/bin/sh\nsshd:x:100:65534:sshd:/var:/bin/false\n" > /etc/passwd + [ -f /etc/group ] || echo -e "root:x:0:\nnogroup:x:65534:\n" > /etc/group + echo "\n\nNOTICE: SSH requires proper root password to be configured, set it now." + passwd +fi + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.ssh_config b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.ssh_config new file mode 100644 index 0000000000..2692e89137 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.client.ssh_config @@ -0,0 +1,37 @@ +# $OpenBSD: ssh_config,v 1.19 2003/08/13 08:46:31 markus Exp $ + +# This is the ssh client system-wide configuration file. See +# ssh_config(5) for more information. This file provides defaults for +# users, and the values can be changed in per-user configuration files +# or on the command line. + +# Configuration data is parsed as follows: +# 1. command line options +# 2. user-specific file +# 3. system-wide file +# Any configuration value is only changed the first time it is set. +# Thus, host-specific definitions should be at the beginning of the +# configuration file, and defaults at the end. + +# Site-wide defaults for various options + +# Host * +# ForwardAgent no +# ForwardX11 no +# RhostsRSAAuthentication no +# RSAAuthentication yes +# PasswordAuthentication yes +# HostbasedAuthentication no +# BatchMode no +# CheckHostIP yes +# AddressFamily any +# ConnectTimeout 0 +# StrictHostKeyChecking ask +# IdentityFile ~/.ssh/identity +# IdentityFile ~/.ssh/id_rsa +# IdentityFile ~/.ssh/id_dsa +# Port 22 +# Protocol 2,1 +# Cipher 3des +# Ciphers aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc,arcfour,aes192-cbc,aes256-cbc +# EscapeChar ~ diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.patch b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.patch new file mode 100644 index 0000000000..7d85a0400e --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.patch @@ -0,0 +1,289 @@ +--- openssh-3.6.1p1/Makefile.in.orig 2003-03-20 17:34:34.000000000 -0700 ++++ openssh-3.6.1p1/Makefile.in 2003-04-25 17:09:00.000000000 -0600 +@@ -27,7 +27,7 @@ + RAND_HELPER=$(libexecdir)/ssh-rand-helper + PRIVSEP_PATH=@PRIVSEP_PATH@ + SSH_PRIVSEP_USER=@SSH_PRIVSEP_USER@ +-STRIP_OPT=@STRIP_OPT@ ++STRIP_OPT= + + PATHS= -DSSHDIR=\"$(sysconfdir)\" \ + -D_PATH_SSH_PROGRAM=\"$(SSH_PROGRAM)\" \ +--- openssh-3.8p1/configure.ac.orig 2004-02-23 22:47:04.000000000 -0700 ++++ openssh-3.8p1/configure.ac 2004-03-19 01:41:47.000000000 -0700 +@@ -481,6 +481,9 @@ + [ + AC_MSG_RESULT(no) + AC_MSG_ERROR([*** compiler cannot create working executables, check config.log ***]) ++ ], ++ [AC_MSG_RESULT(yes) ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) + ] + ) + +@@ -632,6 +635,9 @@ + else + AC_MSG_WARN([zlib version may have security problems]) + fi ++ ], ++ [AC_MSG_RESULT(yes) ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) + ] + ) + +@@ -696,6 +702,9 @@ + [ + AC_MSG_RESULT(no) + AC_DEFINE(BROKEN_ONE_BYTE_DIRENT_D_NAME) ++ ], ++ [AC_MSG_RESULT(yes) ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) + ] + ) + +@@ -727,6 +736,9 @@ + [ + AC_MSG_RESULT(no) + AC_MSG_ERROR([** Incomplete or missing s/key libraries.]) ++ ], ++ [AC_MSG_RESULT(yes) ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) + ]) + fi + ] +@@ -840,7 +852,11 @@ + ], + [AC_MSG_RESULT(yes)], + [AC_DEFINE(BROKEN_SETRESUID) +- AC_MSG_RESULT(not implemented)] ++ AC_MSG_RESULT(not implemented) ++ ], ++ [AC_MSG_RESULT(yes) ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) ++ ] + ) + ]) + +@@ -854,7 +870,11 @@ + ], + [AC_MSG_RESULT(yes)], + [AC_DEFINE(BROKEN_SETRESGID) +- AC_MSG_RESULT(not implemented)] ++ AC_MSG_RESULT(not implemented) ++ ], ++ [AC_MSG_RESULT(yes) ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) ++ ] + ) + ]) + +@@ -890,6 +910,9 @@ + AC_MSG_RESULT(no) + AC_DEFINE(BROKEN_SNPRINTF) + AC_MSG_WARN([****** Your snprintf() function is broken, complain to your vendor]) ++ ], ++ [AC_MSG_RESULT(yes) ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) + ] + ) + fi +@@ -963,7 +986,10 @@ + [ + AC_MSG_RESULT(no) + AC_DEFINE(SSHD_ACQUIRES_CTTY) +- ] ++ ], ++ [AC_MSG_RESULT(yes) ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) ++ ] + ) + fi + +@@ -1096,6 +1122,10 @@ + [ + AC_MSG_RESULT(not found) + AC_MSG_ERROR(OpenSSL version header not found.) ++ ], ++ [ ++ ssl_header_ver="0x0090704fL (OpenSSL 0.9.7d 17 Mar 2004)" ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to $ssl_header_ver]) + ] + ) + +@@ -1129,6 +1159,10 @@ + [ + AC_MSG_RESULT(not found) + AC_MSG_ERROR(OpenSSL library not found.) ++ ], ++ [ ++ ssl_header_ver="0x0090704fL (OpenSSL 0.9.7d 17 Mar 2004)" ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to $ssl_library_ver]) + ] + ) + +@@ -1148,7 +1182,11 @@ + AC_MSG_ERROR([Your OpenSSL headers do not match your library. + Check config.log for details. + Also see contrib/findssl.sh for help identifying header/library mismatches.]) +- ] ++ ], ++ [ ++ AC_MSG_RESULT(yes) ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) ++ ] + ) + + # Some systems want crypt() from libcrypt, *not* the version in OpenSSL, +@@ -1183,6 +1221,11 @@ + # Default to use of the rand helper if OpenSSL doesn't + # seed itself + USE_RAND_HELPER=yes ++ ], ++ [ ++ OPENSSL_SEEDS_ITSELF=yes ++ AC_MSG_RESULT(yes) ++ AC_MSG_WARN([Cannot run test when crosscompiling, defaulted to yes.]) + ] + ) + +@@ -1773,7 +1816,8 @@ + #else + main() { exit(0); } + #endif +- ], [ true ], [ AC_DEFINE(BROKEN_SNPRINTF) ] ++ ], [ true ], [ AC_DEFINE(BROKEN_SNPRINTF) ], ++ [ true ] + ) + fi + +@@ -1893,6 +1937,7 @@ + } + ], + [ ac_cv_have_accrights_in_msghdr="yes" ], ++ [ ac_cv_have_accrights_in_msghdr="no" ], + [ ac_cv_have_accrights_in_msghdr="no" ] + ) + ]) +@@ -1917,7 +1962,8 @@ + } + ], + [ ac_cv_have_control_in_msghdr="yes" ], +- [ ac_cv_have_control_in_msghdr="no" ] ++ [ ac_cv_have_control_in_msghdr="no" ], ++ [ ac_cv_have_control_in_msghdr="yes" ] + ) + ]) + if test "x$ac_cv_have_control_in_msghdr" = "xyes" ; then +@@ -2229,12 +2275,9 @@ + ) + fi + fi +-AC_CHECK_FILE("/dev/ptc", +- [ +- AC_DEFINE_UNQUOTED(HAVE_DEV_PTS_AND_PTC) +- have_dev_ptc=1 +- ] +-) ++AC_MSG_CHECKING([for "/dev/ptc"]) ++AC_MSG_RESULT(no) ++have_dev_ptc=0 + + # Options from here on. Some of these are preset by platform above + AC_ARG_WITH(mantype, +@@ -2329,15 +2372,8 @@ + fi + + # check for /etc/default/login and use it if present. +-AC_ARG_ENABLE(etc-default-login, +- [ --disable-etc-default-login Disable using PATH from /etc/default/login [no]],, +-[ +-AC_CHECK_FILE("/etc/default/login", [ external_path_file=/etc/default/login ]) +- +-if test "x$external_path_file" = "x/etc/default/login"; then +- AC_DEFINE(HAVE_ETC_DEFAULT_LOGIN) +-fi +-]) ++AC_MSG_CHECKING([for "/etc/default/login"]) ++AC_MSG_RESULT(no) + + dnl BSD systems use /etc/login.conf so --with-default-path= has no effect + if test $ac_cv_func_login_getcapbool = "yes" -a \ +--- openssh-3.8p1.orig/sshd_config Fri Sep 27 05:21:58 2002 ++++ openssh-3.8p1/sshd_config Mon Mar 17 14:55:00 2003 +@@ -89,5 +89,8 @@ + #Banner /some/path + #VerifyReverseMapping no + ++ClientAliveInterval 15 ++ClientAliveCountMax 4 ++ + # override default of no subsystems +-Subsystem sftp /usr/libexec/sftp-server ++Subsystem sftp /usr/sbin/sftp-server +--- openssh-3.6.1p1/S50sshd Fri Sep 27 05:21:58 2002 ++++ openssh-3.6.1p1/S50sshd Mon Mar 17 14:55:00 2003 +@@ -0,0 +1,64 @@ ++#!/bin/sh ++# ++# sshd Starts sshd. ++# ++ ++# Make sure the ssh-keygen progam exists ++[ -f /usr/bin/ssh-keygen ] || exit 0 ++ ++# Check for the SSH1 RSA key ++if [ ! -f /etc/ssh_host_key ] ; then ++ echo Generating RSA Key... ++ /usr/bin/ssh-keygen -t rsa1 -f /etc/ssh_host_key -C '' -N '' ++fi ++ ++# Check for the SSH2 RSA key ++if [ ! -f /etc/ssh_host_rsa_key ] ; then ++ echo Generating RSA Key... ++ /usr/bin/ssh-keygen -t rsa -f /etc/ssh_host_rsa_key -C '' -N '' ++fi ++ ++# Check for the SSH2 DSA key ++if [ ! -f /etc/ssh_host_dsa_key ] ; then ++ echo Generating DSA Key... ++ echo THIS CAN TAKE A MINUTE OR TWO DEPENDING ON YOUR PROCESSOR! ++ echo ++ /usr/bin/ssh-keygen -t dsa -f /etc/ssh_host_dsa_key -C '' -N '' ++fi ++ ++umask 077 ++ ++start() { ++ echo -n "Starting sshd: " ++ /usr/sbin/sshd ++ touch /var/lock/sshd ++ echo "OK" ++} ++stop() { ++ echo -n "Stopping sshd: " ++ killall sshd ++ rm -f /var/lock/sshd ++ echo "OK" ++} ++restart() { ++ stop ++ start ++} ++ ++case "$1" in ++ start) ++ start ++ ;; ++ stop) ++ stop ++ ;; ++ restart|reload) ++ restart ++ ;; ++ *) ++ echo $"Usage: $0 {start|stop|restart}" ++ exit 1 ++esac ++ ++exit $? ++ diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.S50sshd-ipk b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.S50sshd-ipk new file mode 100644 index 0000000000..6f77ad9b1c --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.S50sshd-ipk @@ -0,0 +1,45 @@ +#!/bin/sh +# +# sshd Starts sshd. +# + +mkdir -p /var/lock +mkdir -p /var/empty +chmod 600 /var/empty + +umask 077 + +start() { + echo -n "Starting sshd: " + /usr/sbin/sshd + touch /var/lock/sshd + echo "OK" +} +stop() { + echo -n "Stopping sshd: " + killall sshd + rm -f /var/lock/sshd + echo "OK" +} +restart() { + stop + start +} + +case "$1" in + start) + start + ;; + stop) + stop + ;; + restart|reload) + restart + ;; + *) + echo $"Usage: $0 {start|stop|restart}" + exit 1 +esac + +exit $? + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.conffiles b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.conffiles new file mode 100644 index 0000000000..5877b3bdbc --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.conffiles @@ -0,0 +1 @@ +/etc/sshd_config diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.control b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.control new file mode 100644 index 0000000000..943da932d3 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.control @@ -0,0 +1,13 @@ +Package: openssh-server +Priority: optional +Version: 3.8p1-1 +Architecture: mipsel +Maintainer: below0 +Section: net +Depends: zlib libssl +Source: Embedded in the main OpenWrt buildroot +Description: The OpenSSH server daemon. + Allows for access to the system via the SSH client. + Includes: sshd, ssh-keygen + + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.postinst b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.postinst new file mode 100644 index 0000000000..16d2bf4d76 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.postinst @@ -0,0 +1,20 @@ +#!/bin/sh + +# Check for the SSH1 RSA key +if [ ! -f /etc/ssh_host_key ] ; then + echo Generating RSA Key... + /usr/bin/ssh-keygen -t rsa1 -f /etc/ssh_host_key -C '' -N '' +fi + +# Check for the SSH2 RSA key +if [ ! -f /etc/ssh_host_rsa_key ] ; then + echo Generating RSA Key... + /usr/bin/ssh-keygen -t rsa -f /etc/ssh_host_rsa_key -C '' -N '' +fi + +# Check for the SSH2 DSA key +if [ ! -f /etc/ssh_host_dsa_key ] ; then + echo "Generating DSA Key... (Takes a few minutes)" + /usr/bin/ssh-keygen -t dsa -f /etc/ssh_host_dsa_key -C '' -N '' +fi + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.preinst b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.preinst new file mode 100644 index 0000000000..029c78978a --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.preinst @@ -0,0 +1,10 @@ +#!/bin/sh + +# Make sure password and group databases exist +if [ ! -f /etc/passwd ]; then + echo -e "root::0:0::/tmp:/bin/sh\nnobody:x:65534:65534:nobody:/tmp:/bin/sh\nsshd:x:100:65534:sshd:/var:/bin/false\n" > /etc/passwd + [ -f /etc/group ] || echo -e "root:x:0:\nnogroup:x:65534:\n" > /etc/group + echo "\n\nNOTICE: SSH requires proper root password to be configured, set it now." + passwd +fi + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.sshd_config b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.sshd_config new file mode 100644 index 0000000000..22e5dc2128 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.server.sshd_config @@ -0,0 +1,100 @@ +# $OpenBSD: sshd_config,v 1.68 2003/12/29 16:39:50 millert Exp $ + +# This is the sshd server system-wide configuration file. See +# sshd_config(5) for more information. + +# This sshd was compiled with PATH=/usr/bin:/bin:/usr/sbin:/sbin + +# The strategy used for options in the default sshd_config shipped with +# OpenSSH is to specify options with their default value where +# possible, but leave them commented. Uncommented options change a +# default value. + +#Port 22 +#Protocol 2,1 +#ListenAddress 0.0.0.0 +#ListenAddress :: + +# HostKey for protocol version 1 +#HostKey /etc/ssh_host_key +# HostKeys for protocol version 2 +#HostKey /etc/ssh_host_rsa_key +#HostKey /etc/ssh_host_dsa_key + +# Lifetime and size of ephemeral version 1 server key +#KeyRegenerationInterval 1h +#ServerKeyBits 768 + +# Logging +#obsoletes QuietMode and FascistLogging +#SyslogFacility AUTH +#LogLevel INFO + +# Authentication: + +#LoginGraceTime 2m +#PermitRootLogin yes +#StrictModes yes + +#RSAAuthentication yes +#PubkeyAuthentication yes +#AuthorizedKeysFile .ssh/authorized_keys + +# For this to work you will also need host keys in /etc/ssh_known_hosts +#RhostsRSAAuthentication no +# similar for protocol version 2 +#HostbasedAuthentication no +# Change to yes if you don't trust ~/.ssh/known_hosts for +# RhostsRSAAuthentication and HostbasedAuthentication +#IgnoreUserKnownHosts no +# Don't read the user's ~/.rhosts and ~/.shosts files +#IgnoreRhosts yes + +# To disable tunneled clear text passwords, change to no here! +#PasswordAuthentication yes +#PermitEmptyPasswords no + +# Change to no to disable s/key passwords +#ChallengeResponseAuthentication yes + +# Kerberos options +#KerberosAuthentication no +#KerberosOrLocalPasswd yes +#KerberosTicketCleanup yes +#KerberosGetAFSToken no + +# GSSAPI options +#GSSAPIAuthentication no +#GSSAPICleanupCredentials yes + +# Set this to 'yes' to enable PAM authentication (via challenge-response) +# and session processing. Depending on your PAM configuration, this may +# bypass the setting of 'PasswordAuthentication' and 'PermitEmptyPasswords' +#UsePAM no + +#AllowTcpForwarding yes +#GatewayPorts no +#X11Forwarding no +#X11DisplayOffset 10 +#X11UseLocalhost yes +#PrintMotd yes +#PrintLastLog yes +#TCPKeepAlive yes +#UseLogin no +#UsePrivilegeSeparation yes +#PermitUserEnvironment no +#Compression yes +#ClientAliveInterval 0 +#ClientAliveCountMax 3 +#UseDNS yes +#PidFile /var/run/sshd.pid +#MaxStartups 10 + +# no default banner path +#Banner /some/path + +ClientAliveInterval 15 +ClientAliveCountMax 4 + +# override default of no subsystems +Subsystem sftp /usr/sbin/sftp-server diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.sftp-client.control b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.sftp-client.control new file mode 100644 index 0000000000..12949f18f3 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.sftp-client.control @@ -0,0 +1,12 @@ +Package: openssh-sftp-client +Priority: optional +Version: 3.8p1-1 +Architecture: mipsel +Maintainer: below0 +Section: net +Depends: openssh-client +Source: Embedded in the main OpenWrt buildroot +Description: OpenSSH Secure FTP server. + Includes: sftp-server + + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.sftp-server.control b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.sftp-server.control new file mode 100644 index 0000000000..45f5c9aaea --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssh/openssh.sftp-server.control @@ -0,0 +1,12 @@ +Package: openssh-sftp-server +Priority: optional +Version: 3.8p1-1 +Architecture: mipsel +Maintainer: below0 +Section: net +Depends: openssh-server +Source: Embedded in the main OpenWrt buildroot +Description: OpenSSH Secure FTP server. + Includes: sftp-server + + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssl/control b/obsolete-buildroot/sources/openwrt/ipkg/openssl/control new file mode 100644 index 0000000000..cc679a6569 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssl/control @@ -0,0 +1,9 @@ +Package: openssl +Priority: optional +Version: 0.9.7d-1 +Architecture: mipsel +Maintainer: below0 +Section: libs +Source: Embedded in the main OpenWrt buildroot +Description: OpenSSL libraries used for SSL encryption. + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/openssl/openssl.patch b/obsolete-buildroot/sources/openwrt/ipkg/openssl/openssl.patch new file mode 100644 index 0000000000..2e8d50f1cb --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/openssl/openssl.patch @@ -0,0 +1,238 @@ +--- openssl-0.9.7.orig/Configure ++++ openssl-0.9.7/Configure +@@ -1,4 +1,4 @@ +-: ++#!/usr/bin/perl + eval 'exec perl -S $0 ${1+"$@"}' + if $running_under_some_shell; + ## +@@ -373,6 +373,40 @@ + # assembler versions -- currently defunct: + ##"OpenBSD-alpha","gcc:-DTERMIOS -O3 -fomit-frame-pointer:::(unknown):SIXTY_FOUR_BIT_LONG DES_INT DES_PTR DES_RISC2:${alpha_asm}", + ++# Sane Linux configuration values, stolen from the Debian package.... ++"linux-alpha","gcc:-DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-alpha-ev4","gcc:-DTERMIO -O3 -mcpu=ev4 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-alpha-ev5","gcc:-DTERMIO -O3 -mcpu=ev5 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_RISC1 DES_UNROLL:${alpha_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-arm","gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG DES_RISC1::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-freebsd-alpha","gcc:-DTERMIOS -O -fomit-frame-pointer::(unknown):::SIXTY_FOUR_BIT_LONG RC4_CHUNK DES_INT DES_PTR DES_RISC2::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-freebsd-i386", "gcc:-DTERMIOS -DL_ENDIAN -fomit-frame-pointer -O3 -m486 -Wall::-pthread -D_REENTRANT -D_THREAD_SAFE -D_THREADSAFE:::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-hppa","gcc:-DB_ENDIAN -DTERMIO -O2 -Wall::-D_REENTRANT::-ldl:BN_LLONG MD2_CHAR RC4_INDEX::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-hurd-i386","gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -m486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-ia64","gcc:-DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:SIXTY_FOUR_BIT_LONG RC4_CHUNK RC4_CHAR:asm/ia64.o:::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++#"linux-i386","gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::dlfcn:linux-shared:-fPIC", ++"linux-i386","gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-i386-i486","gcc:-DL_ENDIAN -DTERMIO -O3 -march=i486 -mcpu=i486 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-i386-i586","gcc:-DL_ENDIAN -DTERMIO -O3 -march=i586 -mcpu=i586 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-i386-i686/cmov","gcc:-DL_ENDIAN -DTERMIO -O3 -march=i686 -mcpu=i686 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-m68k","gcc:-DB_ENDIAN -DTERMIO -O2 -Wall::-D_REENTRANT::-ldl:BN_LLONG MD2_CHAR RC4_INDEX::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-mips", "gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-mipsel", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-netbsd-i386", "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -m486 -Wall::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-netbsd-m68k", "gcc:-DB_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -Wall::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX DES_UNROLL::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-netbsd-sparc", "gcc:-DB_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -mv8 -Wall::(unknown):::BN_LLONG MD2_CHAR RC4_INDEX DES_UNROLL::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-openbsd-alpha","gcc:-DTERMIOS -O3 -fomit-frame-pointer::(unknown):::SIXTY_FOUR_BIT_LONG DES_INT DES_PTR DES_RISC2::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-openbsd-i386", "gcc:-DL_ENDIAN -DTERMIOS -O3 -fomit-frame-pointer -m486::(unknown):::BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_out_asm}:dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-openbsd-mips","gcc:-O2 -DL_ENDIAN::(unknown)::BN_LLONG MD2_CHAR RC4_INDEX RC4_CHAR DES_UNROLL DES_RISC2 DES_PTR BF_PTR:::::::::::dlfcn:bsd-gcc-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-powerpc","gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG DES_UNROLL DES_RISC2 DES_PTR MD2_CHAR RC4_INDEX::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-s390","gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sh3", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sh4", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sh3eb", "gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sh4eb", "gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sparc","gcc:-DB_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR::::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sparc-v8","gcc:-DB_ENDIAN -DTERMIO -O3 -mcpu=v8 -fomit-frame-pointer -Wall -DBN_DIV2W::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8.o:::::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-sparc-v9","gcc:-DB_ENDIAN -DTERMIO -O3 -mcpu=v9 -Wa,-Av8plus -fomit-frame-pointer -Wall -DULTRASPARC -DBN_DIV2W::-D_REENTRANT::-ldl:BN_LLONG RC4_CHAR RC4_CHUNK DES_UNROLL BF_PTR:asm/sparcv8plus.o:::asm/md5-sparcv8plus.o::::::dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", ++"linux-cris", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -Wall::-D_REENTRANT::-ldl:BN_LLONG::::::::::dlfcn:linux-shared:-fpic::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", + # The intel boxes :-), It would be worth seeing if bsdi-gcc can use the + # bn86-elf.o file file since it is hand tweaked assembler. + "linux-elf", "gcc:-DL_ENDIAN -DTERMIO -O3 -fomit-frame-pointer -m486 -Wall::-D_REENTRANT::-ldl:BN_LLONG ${x86_gcc_des} ${x86_gcc_opts}:${x86_elf_asm}:dlfcn:linux-shared:-fPIC::.so.\$(SHLIB_MAJOR).\$(SHLIB_MINOR)", +--- openssl-0.9.7.orig/crypto/md5/asm/md5-sparcv9.S ++++ openssl-0.9.7/crypto/md5/asm/md5-sparcv9.S +@@ -72,14 +72,14 @@ + #define Dval R8 + + #if defined(MD5_BLOCK_DATA_ORDER) +-# if defined(OPENSSL_SYSNAME_ULTRASPARC) ++/*# if defined(OPENSSL_SYSNAME_ULTRASPARC)*/ + # define LOAD lda + # define X(i) [%i1+i*4]%asi + # define md5_block md5_block_asm_data_order_aligned + # define ASI_PRIMARY_LITTLE 0x88 +-# else ++/*# else + # error "MD5_BLOCK_DATA_ORDER is supported only on UltraSPARC!" +-# endif ++# endif*/ + #else + # define LOAD ld + # define X(i) [%i1+i*4] +--- openssl-0.9.7.orig/crypto/opensslconf.h ++++ openssl-0.9.7/crypto/opensslconf.h +@@ -4,17 +4,38 @@ + /* OpenSSL was configured with the following options: */ + #ifndef OPENSSL_DOING_MAKEDEPEND + ++#ifndef OPENSSL_NO_IDEA ++# define OPENSSL_NO_IDEA ++#endif ++#ifndef OPENSSL_NO_MDC2 ++# define OPENSSL_NO_MDC2 ++#endif ++#ifndef OPENSSL_NO_RC5 ++# define OPENSSL_NO_RC5 ++#endif + #ifndef OPENSSL_NO_KRB5 + # define OPENSSL_NO_KRB5 + #endif + + #endif /* OPENSSL_DOING_MAKEDEPEND */ ++#ifndef OPENSSL_THREADS ++# define OPENSSL_THREADS ++#endif + + /* The OPENSSL_NO_* macros are also defined as NO_* if the application + asks for it. This is a transient feature that is provided for those + who haven't had the time to do the appropriate changes in their + applications. */ + #ifdef OPENSSL_ALGORITHM_DEFINES ++# if defined(OPENSSL_NO_IDEA) && !defined(NO_IDEA) ++# define NO_IDEA ++# endif ++# if defined(OPENSSL_NO_MDC2) && !defined(NO_MDC2) ++# define NO_MDC2 ++# endif ++# if defined(OPENSSL_NO_RC5) && !defined(NO_RC5) ++# define NO_RC5 ++# endif + # if defined(OPENSSL_NO_KRB5) && !defined(NO_KRB5) + # define NO_KRB5 + # endif +@@ -27,7 +48,7 @@ + + #if !(defined(VMS) || defined(__VMS)) /* VMS uses logical names instead */ + #if defined(HEADER_CRYPTLIB_H) && !defined(OPENSSLDIR) +-#define OPENSSLDIR "/usr/local/ssl" ++#define OPENSSLDIR "/usr/lib/ssl" + #endif + #endif + +@@ -79,7 +100,7 @@ + + #if defined(HEADER_BN_H) && !defined(CONFIG_HEADER_BN_H) + #define CONFIG_HEADER_BN_H +-#undef BN_LLONG ++#define BN_LLONG + + /* Should we define BN_DIV2W here? */ + +@@ -98,7 +119,7 @@ + #define CONFIG_HEADER_RC4_LOCL_H + /* if this is defined data[i] is used instead of *data, this is a %20 + * speedup on x86 */ +-#undef RC4_INDEX ++#define RC4_INDEX + #endif + + #if defined(HEADER_BF_LOCL_H) && !defined(CONFIG_HEADER_BF_LOCL_H) +@@ -112,14 +133,14 @@ + /* the following is tweaked from a config script, that is why it is a + * protected undef/define */ + #ifndef DES_PTR +-#undef DES_PTR ++#define DES_PTR + #endif + + /* This helps C compiler generate the correct code for multiple functional + * units. It reduces register dependancies at the expense of 2 more + * registers */ + #ifndef DES_RISC1 +-#undef DES_RISC1 ++#define DES_RISC1 + #endif + + #ifndef DES_RISC2 +@@ -133,7 +154,7 @@ + /* Unroll the inner loop, this sometimes helps, sometimes hinders. + * Very mucy CPU dependant */ + #ifndef DES_UNROLL +-#undef DES_UNROLL ++#define DES_UNROLL + #endif + + /* These default values were supplied by +--- openssl-0.9.7.orig/ssl/ssl_algs.c ++++ openssl-0.9.7/ssl/ssl_algs.c +@@ -109,3 +109,8 @@ + return(1); + } + ++#undef SSLeay_add_ssl_algorithms ++int SSLeay_add_ssl_algorithms(void) ++ { ++ return SSL_library_init(); ++ } +--- openssl-0.9.7.orig/tools/c_rehash.in ++++ openssl-0.9.7/tools/c_rehash.in +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/perl ++#!/usr/bin/perl + + + # Perl c_rehash script, scan all files in a directory +--- openssl-0.9.7.orig/util/clean-depend.pl ++++ openssl-0.9.7/util/clean-depend.pl +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/perl -w ++#!/usr/bin/perl + # Clean the dependency list in a makefile of standard includes... + # Written by Ben Laurie 19 Jan 1999 + +--- openssl-0.9.7.orig/util/extract-names.pl ++++ openssl-0.9.7/util/extract-names.pl +@@ -1,4 +1,4 @@ +-#!/usr/bin/perl ++#!/usr/bin/perl + + $/ = ""; # Eat a paragraph at once. + while() { +--- openssl-0.9.7.orig/util/mkdef.pl ++++ openssl-0.9.7/util/mkdef.pl +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/perl -w ++#!/usr/bin/perl + # + # generate a .def file + # +--- openssl-0.9.7.orig/util/mkerr.pl ++++ openssl-0.9.7/util/mkerr.pl +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/perl -w ++#!/usr/bin/perl + + my $config = "crypto/err/openssl.ec"; + my $debug = 0; +--- openssl-0.9.7.orig/util/mkstack.pl ++++ openssl-0.9.7/util/mkstack.pl +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/perl -w ++#!/usr/bin/perl + + # This is a utility that searches out "DECLARE_STACK_OF()" + # declarations in .h and .c files, and updates/creates/replaces +--- openssl-0.9.7.orig/util/pod2man.pl ++++ openssl-0.9.7/util/pod2man.pl +@@ -1,4 +1,4 @@ +-: #!/usr/bin/perl-5.005 ++#!/usr/bin/perl + eval 'exec /usr/bin/perl -S $0 ${1+"$@"}' + if $running_under_some_shell; + +--- openssl-0.9.7.orig/util/selftest.pl ++++ openssl-0.9.7/util/selftest.pl +@@ -1,4 +1,4 @@ +-#!/usr/local/bin/perl -w ++#!/usr/bin/perl + # + # Run the test suite and generate a report + # diff --git a/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/conffiles b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/conffiles new file mode 100644 index 0000000000..7ebe1156e0 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/conffiles @@ -0,0 +1 @@ +/etc/ppp/ip-up diff --git a/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/control b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/control new file mode 100644 index 0000000000..6996b8ecab --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/control @@ -0,0 +1,10 @@ +Package: pppoecd +Priority: optional +Version: 1.0 +Architecture: mipsel +Maintainer: below0 +Section: net +Source: Embedded in the main openwrt tarball +Description: Linksys PPPoE daemon for access to internet using DSL modems + + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/postrm b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/postrm new file mode 100644 index 0000000000..0d53d99f0f --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/postrm @@ -0,0 +1,4 @@ +#!/bin/sh + +rm -rf /etc/ppp + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/prerm b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/prerm new file mode 100644 index 0000000000..092bf00640 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/CONTROL/prerm @@ -0,0 +1,5 @@ +#!/bin/sh + +killall pppoecd +sleep 3 +killall -9 pppoecd \ No newline at end of file diff --git a/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/pppoecd-pathnames.patch b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/pppoecd-pathnames.patch new file mode 100644 index 0000000000..e6c1099674 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/pppoecd-pathnames.patch @@ -0,0 +1,66 @@ +--- pathnames.h.orig Tue Oct 14 03:09:53 2003 ++++ pathnames.h Sat Jul 10 21:04:34 2004 +@@ -9,37 +9,37 @@ + + #else /* HAVE_PATHS_H */ + #ifndef _PATH_VARRUN +-#define _PATH_VARRUN "/tmp/ppp/" ++#define _PATH_VARRUN "/var/run" + #endif + #define _PATH_DEVNULL "/dev/null" + #endif /* HAVE_PATHS_H */ + + #ifndef _ROOT_PATH +-#define _ROOT_PATH ++#define _ROOT_PATH "/etc" + #endif + +-#define _PATH_UPAPFILE _ROOT_PATH "/tmp/ppp/pap-secrets" +-#define _PATH_CHAPFILE _ROOT_PATH "/tmp/ppp/chap-secrets" +-#define _PATH_SYSOPTIONS _ROOT_PATH "/tmp/ppp/options" +-#define _PATH_IPUP _ROOT_PATH "/tmp/ppp/ip-up" +-#define _PATH_IPDOWN _ROOT_PATH "/tmp/ppp/ip-down" +-#define _PATH_AUTHUP _ROOT_PATH "/tmp/ppp/auth-up" +-#define _PATH_AUTHDOWN _ROOT_PATH "/tmp/ppp/auth-down" +-#define _PATH_TTYOPT _ROOT_PATH "/tmp/ppp/options." +-#define _PATH_CONNERRS _ROOT_PATH "/tmp/ppp/connect-errors" +-#define _PATH_PEERFILES _ROOT_PATH "/tmp/ppp/peers/" +-#define _PATH_RESOLV _ROOT_PATH "/tmp/ppp/resolv.conf" ++#define _PATH_UPAPFILE _ROOT_PATH "/ppp/pap-secrets" ++#define _PATH_CHAPFILE _ROOT_PATH "/ppp/chap-secrets" ++#define _PATH_SYSOPTIONS _ROOT_PATH "/ppp/options" ++#define _PATH_IPUP _ROOT_PATH "/ppp/ip-up" ++#define _PATH_IPDOWN _ROOT_PATH "/ppp/ip-down" ++#define _PATH_AUTHUP _ROOT_PATH "/ppp/auth-up" ++#define _PATH_AUTHDOWN _ROOT_PATH "/ppp/auth-down" ++#define _PATH_TTYOPT _ROOT_PATH "/ppp/options." ++#define _PATH_CONNERRS "/tmp/connect-errors" ++#define _PATH_PEERFILES _ROOT_PATH "/ppp/peers/" ++#define _PATH_RESOLV "/tmp/resolv.conf" + + #define _PATH_USEROPT ".ppprc" + + #ifdef INET6 +-#define _PATH_IPV6UP _ROOT_PATH "/tmp/ppp/ipv6-up" +-#define _PATH_IPV6DOWN _ROOT_PATH "/tmp/ppp/ipv6-down" ++#define _PATH_IPV6UP _ROOT_PATH "/ppp/ipv6-up" ++#define _PATH_IPV6DOWN _ROOT_PATH "/ppp/ipv6-down" + #endif + + #ifdef IPX_CHANGE +-#define _PATH_IPXUP _ROOT_PATH "/tmp/ppp/ipx-up" +-#define _PATH_IPXDOWN _ROOT_PATH "/tmp/ppp/ipx-down" ++#define _PATH_IPXUP _ROOT_PATH "/ppp/ipx-up" ++#define _PATH_IPXDOWN _ROOT_PATH "/ppp/ipx-down" + #endif /* IPX_CHANGE */ + + #ifdef __STDC__ +@@ -48,7 +48,7 @@ + #ifdef HAVE_PATHS_H + #define _PATH_PPPDB "/var/run/pppd.tdb" + #else +-#define _PATH_PPPDB "/tmp/ppp/pppd.tdb" ++#define _PATH_PPPDB "/tmp/pppd.tdb" + #endif + #endif /* __STDC__ */ + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/pppoecd.patch b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/pppoecd.patch new file mode 100644 index 0000000000..4fa4afc254 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/pppoecd.patch @@ -0,0 +1,27 @@ +--- pppoe.c.orig Sat Jul 10 20:55:38 2004 ++++ pppoe.c Sat Jul 10 20:55:55 2004 +@@ -131,8 +131,7 @@ + + if (pppoe_srv_name !=NULL) { + if (strlen (pppoe_srv_name) > 255) { +- poe_error (ses," Service name too long +- (maximum allowed 256 chars)"); ++ poe_error (ses," Service name too long (maximum allowed 256 chars)"); + poe_die(-1); + } + ses->filt->stag = make_filter_tag(PTT_SRV_NAME, +--- Makefile.orig Sun Jul 11 03:26:49 2004 ++++ Makefile Sun Jul 11 03:27:18 2004 +@@ -68,9 +68,9 @@ + all: pppoecd + + install: all +- install -d $(INSTALLDIR)/usr/sbin +- install -m 755 pppoecd $(INSTALLDIR)/usr/sbin +- $(STRIP) $(INSTALLDIR)/usr/sbin/pppoecd ++ install -d $(INSTALLDIR)/sbin ++ install -m 755 pppoecd $(INSTALLDIR)/sbin ++ $(STRIP) $(INSTALLDIR)/sbin/pppoecd + + pppoecd: $(OBJS) + $(LD) -r -o .$@ $^ $(LIBCRYPT) diff --git a/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/root/etc/ppp/ip-up b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/root/etc/ppp/ip-up new file mode 100644 index 0000000000..da432949e7 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/pppoecd/root/etc/ppp/ip-up @@ -0,0 +1,5 @@ +#!/bin/sh + +# set default route +/sbin/route add default gw $IPREMOTE + diff --git a/obsolete-buildroot/sources/openwrt/ipkg/zlib/control b/obsolete-buildroot/sources/openwrt/ipkg/zlib/control new file mode 100644 index 0000000000..608176d812 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/ipkg/zlib/control @@ -0,0 +1,10 @@ +Package: zlib +Priority: optional +Version: 1.1.4-1 +Architecture: mipsel +Maintainer: below0 +Section: libs +Source: Embedded in the main OpenWrt buildroot +Description: zlib is a library implementing the 'deflate' compression system used by many programs. + + diff --git a/obsolete-buildroot/sources/openwrt/kernel/compressed-20040531.tar.bz2 b/obsolete-buildroot/sources/openwrt/kernel/compressed-20040531.tar.bz2 new file mode 100644 index 0000000000..c8e06b8a9b Binary files /dev/null and b/obsolete-buildroot/sources/openwrt/kernel/compressed-20040531.tar.bz2 differ diff --git a/obsolete-buildroot/sources/openwrt/kernel/diag.c b/obsolete-buildroot/sources/openwrt/kernel/diag.c new file mode 100644 index 0000000000..6d93542f84 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/kernel/diag.c @@ -0,0 +1,145 @@ +// replacement diag module +// (c) 2004 openwrt +// mbm at alt dot org +// +// initial release 2004/03/28 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void *sbh; + +// v2.x - - - - - +#define DIAG_GPIO (1<<1) +#define DMZ_GPIO (1<<7) + +static void set_gpio(uint32 mask, uint32 value) { + sb_gpiocontrol(sbh,mask,0); + sb_gpioouten(sbh,mask,mask); + sb_gpioout(sbh,mask,value); +} + +static void v2_set_diag(u8 state) { + set_gpio(DIAG_GPIO,state); +} +static void v2_set_dmz(u8 state) { + set_gpio(DMZ_GPIO,state); +} + +// v1.x - - - - - +#define LED_DIAG 0x13 +#define LED_DMZ 0x12 + +static void v1_set_diag(u8 state) { + if (!state) { + *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DIAG)=0xFF; + } else { + *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DIAG); + } +} +static void v1_set_dmz(u8 state) { + if (!state) { + *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DMZ)=0xFF; + } else { + *(volatile u8*)(KSEG1ADDR(BCM4710_EUART)+LED_DMZ); + } +} + +// - - - - - +static void ignore(u8 ignored) {}; + +// - - - - - +#define BIT_DMZ 0x01 +#define BIT_DIAG 0x04 + +void (*set_diag)(u8 state); +void (*set_dmz)(u8 state); + +static unsigned int diag = 0; +static struct timer_list timer; + +static void diag_change() +{ + printk(KERN_INFO "led -> %02x\n",diag); + + set_diag(0xFF); // off + set_dmz(0xFF); // off + + if(diag & BIT_DIAG) + set_diag(0x00); // on + if(diag & BIT_DMZ) + set_dmz(0x00); // on +} + +static int proc_diag(ctl_table *table, int write, struct file *filp, + void *buffer, size_t *lenp) +{ + int r; + r = proc_dointvec(table, write, filp, buffer, lenp); + if (write && !r) { + diag_change(); + } + return r; +} + +// - - - - - +static struct ctl_table_header *diag_sysctl_header; + +static ctl_table sys_diag[] = { + { + ctl_name: 2000, + procname: "diag", + data: &diag, + maxlen: sizeof(diag), + mode: 0644, + proc_handler: proc_diag + }, + { 0 } +}; + +static int __init diag_init() +{ + u32 board_type; + sbh = sb_kattach(); + sb_gpiosetcore(sbh); + + board_type = sb_boardtype(sbh); + printk(KERN_INFO "diag board_type: %08x\n",board_type); + + if (board_type & 0x400) { + set_diag=v1_set_diag; + set_dmz=v1_set_dmz; + if (board_type==0x41d) { + printk(KERN_INFO "buffalo hack.\n"); + set_diag=ignore; + set_dmz=v2_set_dmz; + } + board_type=1; + } else { + board_type=2; + set_diag=v2_set_diag; + set_dmz=v2_set_dmz; + } + printk(KERN_INFO "using v%d hardware\n",board_type); + + diag_sysctl_header = register_sysctl_table(sys_diag, 0); + diag_change(); + + return 0; +} + +static void __exit diag_exit() +{ + unregister_sysctl_table(diag_sysctl_header); + del_timer(&timer); +} + +module_init(diag_init); +module_exit(diag_exit); diff --git a/obsolete-buildroot/sources/openwrt/kernel/linux.config b/obsolete-buildroot/sources/openwrt/kernel/linux.config new file mode 100644 index 0000000000..69e7c6e7e1 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/kernel/linux.config @@ -0,0 +1,872 @@ +# +# Automatically generated make config: don't edit +# +CONFIG_MIPS=y +CONFIG_MIPS32=y +# CONFIG_MIPS64 is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y + +# +# Loadable module support +# +CONFIG_MODULES=y +# CONFIG_MODVERSIONS is not set +# CONFIG_KMOD is not set + +# +# Machine selection +# +# CONFIG_ACER_PICA_61 is not set +# CONFIG_MIPS_DB1000 is not set +# CONFIG_MIPS_DB1100 is not set +# CONFIG_MIPS_DB1500 is not set +# CONFIG_MIPS_PB1000 is not set +# CONFIG_MIPS_PB1100 is not set +# CONFIG_MIPS_PB1500 is not set +# CONFIG_BAGET_MIPS is not set +# CONFIG_CASIO_E55 is not set +# CONFIG_MIPS_COBALT is not set +# CONFIG_DECSTATION is not set +# CONFIG_MIPS_EV64120 is not set +# CONFIG_MIPS_EV96100 is not set +# CONFIG_MIPS_IVR is not set +# CONFIG_HP_LASERJET is not set +# CONFIG_IBM_WORKPAD is not set +# CONFIG_LASAT is not set +# CONFIG_MIPS_ITE8172 is not set +# CONFIG_MIPS_ATLAS is not set +# CONFIG_MIPS_MAGNUM_4000 is not set +# CONFIG_MIPS_MALTA is not set +# CONFIG_MIPS_SEAD is not set +# CONFIG_MOMENCO_OCELOT is not set +# CONFIG_MOMENCO_OCELOT_G is not set +# CONFIG_DDB5074 is not set +# CONFIG_DDB5476 is not set +# CONFIG_DDB5477 is not set +# CONFIG_NEC_OSPREY is not set +# CONFIG_NEC_EAGLE is not set +# CONFIG_OLIVETTI_M700 is not set +# CONFIG_NINO is not set +# CONFIG_SGI_IP22 is not set +# CONFIG_SGI_IP27 is not set +# CONFIG_SGI_IP32 is not set +# CONFIG_SIBYTE_SB1xxx_SOC is not set +CONFIG_MIPS_BRCM=y +CONFIG_BCM947XX=y +CONFIG_BCM4710=y +CONFIG_BCM4310=y +CONFIG_BCM4704=y +# CONFIG_BCM5365 is not set +# CONFIG_SNI_RM200_PCI is not set +# CONFIG_TOSHIBA_JMR3927 is not set +# CONFIG_VICTOR_MPC30X is not set +# CONFIG_ZAO_CAPCELLA is not set +# CONFIG_HIGHMEM is not set +CONFIG_RWSEM_GENERIC_SPINLOCK=y +# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set +CONFIG_CMDLINE="root=/dev/mtdblock2 rootfstype=squashfs init=/etc/preinit noinitrd console=ttyS0,115200" +CONFIG_PCI=y +CONFIG_NONCOHERENT_IO=y +CONFIG_NEW_TIME_C=y +CONFIG_NEW_IRQ=y +CONFIG_HND=y +# CONFIG_MIPS_AU1000 is not set + +# +# CPU selection +# +CONFIG_CPU_MIPS32=y +# CONFIG_CPU_MIPS64 is not set +# CONFIG_CPU_R3000 is not set +# CONFIG_CPU_TX39XX is not set +# CONFIG_CPU_VR41XX is not set +# CONFIG_CPU_R4300 is not set +# CONFIG_CPU_R4X00 is not set +# CONFIG_CPU_TX49XX is not set +# CONFIG_CPU_R5000 is not set +# CONFIG_CPU_R5432 is not set +# CONFIG_CPU_R6000 is not set +# CONFIG_CPU_NEVADA is not set +# CONFIG_CPU_R8000 is not set +# CONFIG_CPU_R10000 is not set +# CONFIG_CPU_RM7000 is not set +# CONFIG_CPU_SB1 is not set +CONFIG_CPU_HAS_PREFETCH=y +# CONFIG_VTAG_ICACHE is not set +# CONFIG_64BIT_PHYS_ADDR is not set +# CONFIG_CPU_ADVANCED is not set +CONFIG_CPU_HAS_LLSC=y +# CONFIG_CPU_HAS_LLDSCD is not set +# CONFIG_CPU_HAS_WB is not set +CONFIG_CPU_HAS_SYNC=y + +# +# General setup +# +CONFIG_CPU_LITTLE_ENDIAN=y +CONFIG_NET=y +# CONFIG_PCI_NAMES is not set +# CONFIG_ISA is not set +# CONFIG_EISA is not set +# CONFIG_TC is not set +# CONFIG_MCA is not set +# CONFIG_SBUS is not set +CONFIG_HOTPLUG=y + +# +# PCMCIA/CardBus support +# +# CONFIG_PCMCIA is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set +# CONFIG_HOTPLUG_PCI_COMPAQ is not set +# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set +# CONFIG_HOTPLUG_PCI_ACPI is not set +# CONFIG_SYSVIPC is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_PRINT_SYSCALLS is not set +CONFIG_KCORE_ELF=y +# CONFIG_KCORE_AOUT is not set +# CONFIG_BINFMT_AOUT is not set +CONFIG_BINFMT_ELF=y +# CONFIG_MIPS32_COMPAT is not set +# CONFIG_MIPS32_O32 is not set +# CONFIG_MIPS32_N32 is not set +# CONFIG_BINFMT_ELF32 is not set +# CONFIG_BINFMT_MISC is not set +# CONFIG_PM is not set + +# +# Memory Technology Devices (MTD) +# +CONFIG_MTD=y +# CONFIG_MTD_DEBUG is not set +CONFIG_MTD_PARTITIONS=y +# CONFIG_MTD_CONCAT is not set +# CONFIG_MTD_REDBOOT_PARTS is not set + +# +# User Modules And Translation Layers +# +CONFIG_MTD_CHAR=y +# CONFIG_MTD_BLOCK is not set +CONFIG_MTD_BLOCK_RO=y +# CONFIG_FTL is not set +# CONFIG_NFTL is not set + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +# CONFIG_MTD_JEDECPROBE is not set +CONFIG_MTD_GEN_PROBE=y +CONFIG_MTD_CFI_ADV_OPTIONS=y +CONFIG_MTD_CFI_NOSWAP=y +# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set +# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set +CONFIG_MTD_CFI_GEOMETRY=y +# CONFIG_MTD_CFI_B1 is not set +CONFIG_MTD_CFI_B2=y +# CONFIG_MTD_CFI_B4 is not set +CONFIG_MTD_CFI_I1=y +# CONFIG_MTD_CFI_I2 is not set +# CONFIG_MTD_CFI_I4 is not set +CONFIG_MTD_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_SSTSTD=y +# CONFIG_MTD_RAM is not set +# CONFIG_MTD_ROM is not set +# CONFIG_MTD_ABSENT is not set +# CONFIG_MTD_OBSOLETE_CHIPS is not set +# CONFIG_MTD_AMDSTD is not set +# CONFIG_MTD_SHARP is not set +# CONFIG_MTD_JEDEC is not set + +# +# Mapping drivers for chip access +# +# CONFIG_MTD_PHYSMAP is not set +CONFIG_MTD_BCM947XX=y +# CONFIG_MTD_PB1000 is not set +# CONFIG_MTD_PB1500 is not set +# CONFIG_MTD_PB1100 is not set +# CONFIG_MTD_CSTM_MIPS_IXX is not set +# CONFIG_MTD_OCELOT is not set +# CONFIG_MTD_LASAT is not set +# CONFIG_MTD_PCI is not set + +# +# Self-contained MTD device drivers +# +CONFIG_MTD_SFLASH=y +# CONFIG_MTD_PMC551 is not set +# CONFIG_MTD_SLRAM is not set +# CONFIG_MTD_MTDRAM is not set +# CONFIG_MTD_BLKMTD is not set + +# +# Disk-On-Chip Device Drivers +# +# CONFIG_MTD_DOC1000 is not set +# CONFIG_MTD_DOC2000 is not set +# CONFIG_MTD_DOC2001 is not set +# CONFIG_MTD_DOCPROBE is not set + +# +# NAND Flash Device Drivers +# +# CONFIG_MTD_NAND is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play configuration +# +# CONFIG_PNP is not set +# CONFIG_ISAPNP is not set + +# +# Block devices +# +# CONFIG_BLK_DEV_MSYS is not set +# CONFIG_NOROOT is not set +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_DEV_XD is not set +# CONFIG_PARIDE is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_CISS_SCSI_TAPE is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +CONFIG_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_NBD=m +# CONFIG_BLK_DEV_RAM is not set +# CONFIG_BLK_DEV_INITRD is not set +# CONFIG_BLK_STATS is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set +# CONFIG_BLK_DEV_MD is not set +# CONFIG_MD_LINEAR is not set +# CONFIG_MD_RAID0 is not set +# CONFIG_MD_RAID1 is not set +# CONFIG_MD_RAID5 is not set +# CONFIG_MD_MULTIPATH is not set +# CONFIG_BLK_DEV_LVM is not set + +# +# Networking options +# +CONFIG_PACKET=y +CONFIG_PACKET_MMAP=y +CONFIG_NETLINK_DEV=m +CONFIG_NETFILTER=y +# CONFIG_NETFILTER_DEBUG is not set +# CONFIG_FILTER is not set +CONFIG_UNIX=y +CONFIG_NETSWAP=y +CONFIG_INET=y +# CONFIG_IP_MULTICAST is not set +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_ROUTE_FWMARK=y +CONFIG_IP_ROUTE_NAT=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +CONFIG_IP_ROUTE_TOS=y +# CONFIG_IP_ROUTE_VERBOSE is not set +# CONFIG_IP_ROUTE_LARGE_TABLES is not set +# CONFIG_IP_PNP is not set +CONFIG_NET_IPIP=m +CONFIG_NET_IPGRE=m +# CONFIG_ARPD is not set +# CONFIG_INET_ECN is not set +# CONFIG_SYN_COOKIES is not set + +# +# IP: Netfilter Configuration +# +CONFIG_IP_NF_CONNTRACK=y +CONFIG_IP_NF_FTP=y +CONFIG_IP_NF_H323=y +CONFIG_IP_NF_CONNTRACK_MARK=y +# CONFIG_IP_NF_AMANDA is not set +CONFIG_IP_NF_TFTP=y +CONFIG_IP_NF_IRC=y +CONFIG_IP_NF_CT_PROTO_GRE=y +CONFIG_IP_NF_PPTP=y +CONFIG_IP_NF_MMS=y +CONFIG_IP_NF_QUEUE=m +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_LIMIT=m +CONFIG_IP_NF_SET=m +CONFIG_IP_NF_SET_MAX=256 +CONFIG_IP_NF_SET_IPMAP=m +CONFIG_IP_NF_SET_PORTMAP=m +CONFIG_IP_NF_SET_MACIPMAP=m +CONFIG_IP_NF_SET_IPHASH=m +CONFIG_IP_NF_MATCH_QUOTA=m +CONFIG_IP_NF_POOL=m +CONFIG_IP_POOL_STATISTICS=y +CONFIG_IP_NF_MATCH_IPRANGE=m +CONFIG_IP_NF_MATCH_DSTLIMIT=m +CONFIG_IP_NF_MATCH_MAC=m +CONFIG_IP_NF_MATCH_PKTTYPE=m +CONFIG_IP_NF_MATCH_MARK=y +CONFIG_IP_NF_MATCH_MULTIPORT=m +CONFIG_IP_NF_MATCH_TOS=m +CONFIG_IP_NF_MATCH_CONDITION=m +# CONFIG_IP_NF_MATCH_RANDOM is not set +CONFIG_IP_NF_MATCH_PSD=m +# CONFIG_IP_NF_MATCH_OSF is not set +# CONFIG_IP_NF_MATCH_NTH is not set +CONFIG_IP_NF_MATCH_IPV4OPTIONS=m +# CONFIG_IP_NF_MATCH_FUZZY is not set +CONFIG_IP_NF_MATCH_RECENT=m +CONFIG_IP_NF_MATCH_ECN=m +CONFIG_IP_NF_MATCH_DSCP=m +CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_LENGTH=m +# CONFIG_IP_NF_MATCH_U32 is not set +CONFIG_IP_NF_MATCH_TTL=m +CONFIG_IP_NF_MATCH_TCPMSS=y +# CONFIG_IP_NF_MATCH_REALM is not set +CONFIG_IP_NF_MATCH_HELPER=m +CONFIG_IP_NF_MATCH_STATE=y +CONFIG_IP_NF_MATCH_CONNMARK=m +CONFIG_IP_NF_MATCH_CONNLIMIT=m +CONFIG_IP_NF_MATCH_CONNTRACK=m +CONFIG_IP_NF_MATCH_UNCLEAN=m +CONFIG_IP_NF_MATCH_STRING=m +# CONFIG_IP_NF_MATCH_OWNER is not set +CONFIG_IP_NF_MATCH_PHYSDEV=m +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_IP_NF_TARGET_NETLINK=m +CONFIG_IP_NF_TARGET_IPV4OPTSSTRIP=m +CONFIG_IP_NF_TARGET_MIRROR=m +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_NAT_NEEDED=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_NAT_H323=y +# CONFIG_IP_NF_TARGET_SAME is not set +# CONFIG_IP_NF_TARGET_NETMAP is not set +CONFIG_IP_NF_NAT_PPTP=y +CONFIG_IP_NF_NAT_PROTO_GRE=y +# CONFIG_IP_NF_NAT_LOCAL is not set +CONFIG_IP_NF_NAT_SNMP_BASIC=m +CONFIG_IP_NF_NAT_IRC=y +CONFIG_IP_NF_NAT_MMS=y +CONFIG_IP_NF_NAT_FTP=y +CONFIG_IP_NF_NAT_TFTP=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_TARGET_TOS=m +CONFIG_IP_NF_TARGET_ECN=m +CONFIG_IP_NF_TARGET_DSCP=m +CONFIG_IP_NF_TARGET_MARK=y +CONFIG_IP_NF_TARGET_IPMARK=m +CONFIG_IP_NF_TARGET_CLASSIFY=m +CONFIG_IP_NF_TARGET_LOG=y +CONFIG_IP_NF_TARGET_CONNMARK=m +CONFIG_IP_NF_TARGET_TTL=m +CONFIG_IP_NF_TARGET_ULOG=m +CONFIG_IP_NF_TARGET_TCPMSS=y +# CONFIG_IP_NF_RAW is not set +CONFIG_IP_NF_ARPTABLES=m +CONFIG_IP_NF_ARPFILTER=m +CONFIG_IP_NF_ARP_MANGLE=m +CONFIG_IPV6=m + +# +# IPv6: Netfilter Configuration +# +CONFIG_IP6_NF_QUEUE=m +CONFIG_IP6_NF_IPTABLES=m +CONFIG_IP6_NF_MATCH_LIMIT=m +CONFIG_IP6_NF_MATCH_MAC=m +# CONFIG_IP6_NF_MATCH_RANDOM is not set +# CONFIG_IP6_NF_MATCH_NTH is not set +# CONFIG_IP6_NF_MATCH_FUZZY is not set +# CONFIG_IP6_NF_MATCH_RT is not set +# CONFIG_IP6_NF_MATCH_OPTS is not set +# CONFIG_IP6_NF_MATCH_FRAG is not set +# CONFIG_IP6_NF_MATCH_HL is not set +CONFIG_IP6_NF_MATCH_MULTIPORT=m +CONFIG_IP6_NF_MATCH_OWNER=m +CONFIG_IP6_NF_MATCH_MARK=m +# CONFIG_IP6_NF_MATCH_IPV6HEADER is not set +# CONFIG_IP6_NF_MATCH_AHESP is not set +CONFIG_IP6_NF_MATCH_LENGTH=m +CONFIG_IP6_NF_MATCH_EUI64=m +CONFIG_IP6_NF_FILTER=m +CONFIG_IP6_NF_TARGET_REJECT=m +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_TARGET_LOG=m +CONFIG_IP6_NF_MANGLE=m +CONFIG_IP6_NF_TARGET_MARK=m +# CONFIG_KHTTPD is not set +# CONFIG_ATM is not set +CONFIG_VLAN_8021Q=y + +# +# +# +# CONFIG_IPX is not set +# CONFIG_ATALK is not set + +# +# Appletalk devices +# +# CONFIG_DEV_APPLETALK is not set +# CONFIG_DECNET is not set +CONFIG_BRIDGE=y +CONFIG_BRIDGE_NF_EBTABLES=m +CONFIG_BRIDGE_EBT_T_FILTER=m +CONFIG_BRIDGE_EBT_T_NAT=m +CONFIG_BRIDGE_EBT_BROUTE=m +CONFIG_BRIDGE_EBT_LOG=m +CONFIG_BRIDGE_EBT_IPF=m +CONFIG_BRIDGE_EBT_ARPF=m +CONFIG_BRIDGE_EBT_AMONG=m +CONFIG_BRIDGE_EBT_LIMIT=m +CONFIG_BRIDGE_EBT_VLANF=m +CONFIG_BRIDGE_EBT_802_3=m +CONFIG_BRIDGE_EBT_PKTTYPE=m +CONFIG_BRIDGE_EBT_STP=m +CONFIG_BRIDGE_EBT_MARKF=m +CONFIG_BRIDGE_EBT_ARPREPLY=m +CONFIG_BRIDGE_EBT_SNAT=m +CONFIG_BRIDGE_EBT_DNAT=m +CONFIG_BRIDGE_EBT_REDIRECT=m +CONFIG_BRIDGE_EBT_MARK_T=m +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_LLC is not set +# CONFIG_NET_DIVERT is not set +# CONFIG_ECONET is not set +CONFIG_WAN_ROUTER=m +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set + +# +# QoS and/or fair queueing +# +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_CBQ=m +CONFIG_NET_SCH_HTB=m +CONFIG_NET_SCH_CSZ=m +CONFIG_NET_SCH_PRIO=m +CONFIG_NET_SCH_RED=m +CONFIG_NET_SCH_SFQ=m +CONFIG_NET_SCH_TEQL=m +CONFIG_NET_SCH_TBF=m +CONFIG_NET_SCH_GRED=m +CONFIG_NET_SCH_DSMARK=m +CONFIG_NET_SCH_INGRESS=m +CONFIG_NET_QOS=y +CONFIG_NET_ESTIMATOR=y +CONFIG_NET_CLS=y +CONFIG_NET_CLS_TCINDEX=m +CONFIG_NET_CLS_ROUTE4=m +CONFIG_NET_CLS_ROUTE=y +CONFIG_NET_CLS_FW=m +CONFIG_NET_CLS_U32=m +CONFIG_NET_CLS_RSVP=m +CONFIG_NET_CLS_RSVP6=m +CONFIG_NET_CLS_POLICE=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set +# CONFIG_PHONE_IXJ is not set +# CONFIG_PHONE_IXJ_PCMCIA is not set + +# +# ATA/IDE/MFM/RLL support +# +# CONFIG_IDE is not set +# CONFIG_BLK_DEV_IDE_MODES is not set +# CONFIG_BLK_DEV_HD is not set + +# +# SCSI support +# +# CONFIG_SCSI is not set + +# +# I2O device support +# +# CONFIG_I2O is not set +# CONFIG_I2O_PCI is not set +# CONFIG_I2O_BLOCK is not set +# CONFIG_I2O_LAN is not set +# CONFIG_I2O_SCSI is not set +# CONFIG_I2O_PROC is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y + +# +# Broadcom HND network devices +# +CONFIG_HND=y +# CONFIG_IL is not set +CONFIG_ET=m +# CONFIG_ET_4413 is not set +CONFIG_ET_47XX=y +CONFIG_WL=m +CONFIG_WL_AP=y +CONFIG_WL_STA=y + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set +# CONFIG_ETHERTAP is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +# CONFIG_SUNLANCE is not set +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNBMAC is not set +# CONFIG_SUNQE is not set +# CONFIG_SUNGEM is not set +# CONFIG_NET_VENDOR_3COM is not set +# CONFIG_LANCE is not set +# CONFIG_NET_VENDOR_SMC is not set +# CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_HP100 is not set +# CONFIG_NET_ISA is not set +# CONFIG_NET_PCI is not set +# CONFIG_NET_POCKET is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_MYRI_SBUS is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_SK98LIN is not set +# CONFIG_TIGON3 is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PLIP is not set +CONFIG_PPP=y +# CONFIG_PPP_MULTILINK is not set +# CONFIG_PPP_FILTER is not set +CONFIG_PPP_ASYNC=y +# CONFIG_PPP_SYNC_TTY is not set +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPPOE=m +# CONFIG_SLIP is not set + +# +# Wireless LAN (non-hamradio) +# +CONFIG_NET_RADIO=y +# CONFIG_STRIP is not set +# CONFIG_WAVELAN is not set +# CONFIG_ARLAN is not set +# CONFIG_AIRONET4500 is not set +# CONFIG_AIRONET4500_NONCS is not set +# CONFIG_AIRONET4500_PROC is not set +# CONFIG_AIRO is not set +# CONFIG_HERMES is not set +# CONFIG_PLX_HERMES is not set +# CONFIG_PCI_HERMES is not set +CONFIG_NET_WIRELESS=y + +# +# Token Ring devices +# +# CONFIG_TR is not set +# CONFIG_NET_FC is not set +# CONFIG_RCPCI is not set +CONFIG_SHAPER=m + +# +# Wan interfaces +# +# CONFIG_WAN is not set + +# +# Amateur Radio support +# +# CONFIG_HAMRADIO is not set + +# +# IrDA (infrared) support +# +# CONFIG_IRDA is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Input core support +# +# CONFIG_INPUT is not set +# CONFIG_INPUT_KEYBDEV is not set +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_EVDEV is not set + +# +# Character devices +# +# CONFIG_VT is not set +CONFIG_SERIAL=y +CONFIG_SERIAL_CONSOLE=y +# CONFIG_SERIAL_EXTENDED is not set +# CONFIG_SERIAL_NONSTANDARD is not set +CONFIG_UNIX98_PTYS=y +CONFIG_UNIX98_PTY_COUNT=128 + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# Mice +# +# CONFIG_BUSMOUSE is not set +# CONFIG_MOUSE is not set + +# +# Joysticks +# +# CONFIG_INPUT_GAMEPORT is not set + +# +# Input core support is needed for gameports +# + +# +# Input core support is needed for joysticks +# +# CONFIG_QIC02_TAPE is not set + +# +# Watchdog Cards +# +CONFIG_WATCHDOG=y +CONFIG_WATCHDOG_NOWAYOUT=y +# CONFIG_ACQUIRE_WDT is not set +# CONFIG_ADVANTECH_WDT is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_SC520_WDT is not set +# CONFIG_PCWATCHDOG is not set +# CONFIG_EUROTECH_WDT is not set +# CONFIG_IB700_WDT is not set +# CONFIG_WAFER_WDT is not set +# CONFIG_I810_TCO is not set +# CONFIG_MIXCOMWD is not set +# CONFIG_60XX_WDT is not set +# CONFIG_SC1200_WDT is not set +CONFIG_SOFT_WATCHDOG=y +# CONFIG_W83877F_WDT is not set +# CONFIG_WDT is not set +# CONFIG_WDTPCI is not set +# CONFIG_MACHZ_WDT is not set +# CONFIG_INDYDOG is not set +# CONFIG_AMD7XX_TCO is not set +# CONFIG_AMD_PM768 is not set +# CONFIG_NVRAM is not set +# CONFIG_RTC is not set +# CONFIG_DTLK is not set +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set + +# +# Ftape, the floppy tape device driver +# +# CONFIG_FTAPE is not set +# CONFIG_AGP is not set +# CONFIG_DRM is not set + +# +# File systems +# +CONFIG_BLKDEV_SWAP=m +# CONFIG_QUOTA is not set +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_REISERFS_FS is not set +# CONFIG_REISERFS_CHECK is not set +# CONFIG_REISERFS_PROC_INFO is not set +# CONFIG_ADFS_FS is not set +# CONFIG_ADFS_FS_RW is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BEFS_DEBUG is not set +# CONFIG_BFS_FS is not set +# CONFIG_EXT3_FS is not set +# CONFIG_JBD is not set +# CONFIG_JBD_DEBUG is not set +# CONFIG_FAT_FS is not set +# CONFIG_MSDOS_FS is not set +# CONFIG_UMSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_JFFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +# CONFIG_JFFS2_BBC_ARMLIB is not set +CONFIG_JFFS2_BBC_LZO=y +CONFIG_JFFS2_BBC_LZARI=y +CONFIG_JFFS2_BBC_LZHD=y +CONFIG_JFFS2_BBC_LZSS=y +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +# CONFIG_TMPFS is not set +CONFIG_RAMFS=y +# CONFIG_ISO9660_FS is not set +# CONFIG_JOLIET is not set +# CONFIG_ZISOFS is not set +# CONFIG_JFS_FS is not set +# CONFIG_JFS_DEBUG is not set +# CONFIG_JFS_STATISTICS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set +# CONFIG_HPFS_FS is not set +CONFIG_PROC_FS=y +CONFIG_DEVFS_FS=y +CONFIG_DEVFS_MOUNT=y +# CONFIG_DEVFS_DEBUG is not set +# CONFIG_DEVPTS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_EXT2_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set +# CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set + +# +# Network File Systems +# +# CONFIG_CODA_FS is not set +# CONFIG_INTERMEZZO_FS is not set +CONFIG_NFS_FS=m +CONFIG_NFS_V3=y +# CONFIG_ROOT_NFS is not set +CONFIG_SWAP_VIA_NFS=m +CONFIG_NETSWAP=y +# CONFIG_NFSD is not set +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_TCP is not set +CONFIG_SUNRPC=m +CONFIG_LOCKD=m +CONFIG_LOCKD_V4=y +# CONFIG_SMB_FS is not set +# CONFIG_NCP_FS is not set +# CONFIG_NCPFS_PACKET_SIGNING is not set +# CONFIG_NCPFS_IOCTL_LOCKING is not set +# CONFIG_NCPFS_STRONG is not set +# CONFIG_NCPFS_NFS_NS is not set +# CONFIG_NCPFS_OS2_NS is not set +# CONFIG_NCPFS_SMALLDOS is not set +# CONFIG_NCPFS_NLS is not set +# CONFIG_NCPFS_EXTRAS is not set +# CONFIG_ZISOFS_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +# CONFIG_MSDOS_PARTITION is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_EFI_PARTITION is not set +# CONFIG_SMB_NLS is not set +# CONFIG_NLS is not set + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +# CONFIG_USB is not set + +# +# Support for USB gadgets +# +# CONFIG_USB_GADGET is not set + +# +# Bluetooth support +# +# CONFIG_BLUEZ is not set + +# +# Kernel hacking +# +CONFIG_CROSSCOMPILE=y +# CONFIG_KERNPROF is not set +# CONFIG_MCOUNT is not set +# CONFIG_DEBUG is not set +CONFIG_MAGIC_SYSRQ=y +# CONFIG_MIPS_UNCACHED is not set +# CONFIG_KTRACE is not set +# CONFIG_HWSIM is not set + +# +# Library routines +# +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y diff --git a/obsolete-buildroot/sources/openwrt/kernel/patches/100-revert_netfilter.patch b/obsolete-buildroot/sources/openwrt/kernel/patches/100-revert_netfilter.patch new file mode 100644 index 0000000000..4d8b0a1f62 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/kernel/patches/100-revert_netfilter.patch @@ -0,0 +1,5823 @@ +diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack.h +--- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack.h 2003-08-12 07:43:11.000000000 -0400 ++++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack.h 2004-05-09 04:13:03.000000000 -0400 +@@ -45,39 +45,27 @@ + + #include + #include +-#include + + /* per conntrack: protocol private data */ + union ip_conntrack_proto { + /* insert conntrack proto private data here */ +- struct ip_ct_gre gre; + struct ip_ct_tcp tcp; + struct ip_ct_icmp icmp; + }; + + union ip_conntrack_expect_proto { + /* insert expect proto private data here */ +- struct ip_ct_gre_expect gre; + }; + + /* Add protocol helper include file here */ +-#include +-#include +-#include +- + #include + #include +-#include + + /* per expectation: application helper private data */ + union ip_conntrack_expect_help { + /* insert conntrack helper private data (expect) here */ +- struct ip_ct_pptp_expect exp_pptp_info; +- struct ip_ct_mms_expect exp_mms_info; +- struct ip_ct_h225_expect exp_h225_info; + struct ip_ct_ftp_expect exp_ftp_info; + struct ip_ct_irc_expect exp_irc_info; +- struct ip_autofw_expect exp_autofw_info; + + #ifdef CONFIG_IP_NF_NAT_NEEDED + union { +@@ -89,21 +77,16 @@ + /* per conntrack: application helper private data */ + union ip_conntrack_help { + /* insert conntrack helper private data (master) here */ +- struct ip_ct_pptp_master ct_pptp_info; +- struct ip_ct_mms_master ct_mms_info; +- struct ip_ct_h225_master ct_h225_info; + struct ip_ct_ftp_master ct_ftp_info; + struct ip_ct_irc_master ct_irc_info; + }; + + #ifdef CONFIG_IP_NF_NAT_NEEDED + #include +-#include + + /* per conntrack: nat application helper private data */ + union ip_conntrack_nat_help { + /* insert nat helper private data here */ +- struct ip_nat_pptp nat_pptp_info; + }; + #endif + +@@ -275,9 +258,5 @@ + } + + extern unsigned int ip_conntrack_htable_size; +- +-/* connection tracking time out variables. */ +-extern int sysctl_ip_conntrack_tcp_timeouts[10]; +-extern int sysctl_ip_conntrack_udp_timeouts[2]; + #endif /* __KERNEL__ */ + #endif /* _IP_CONNTRACK_H */ +diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_h323.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_h323.h +--- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_h323.h 2003-07-04 04:12:27.000000000 -0400 ++++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_h323.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,30 +0,0 @@ +-#ifndef _IP_CONNTRACK_H323_H +-#define _IP_CONNTRACK_H323_H +-/* H.323 connection tracking. */ +- +-#ifdef __KERNEL__ +-/* Protects H.323 related data */ +-DECLARE_LOCK_EXTERN(ip_h323_lock); +-#endif +- +-/* Default H.225 port */ +-#define H225_PORT 1720 +- +-/* This structure is per expected connection */ +-struct ip_ct_h225_expect { +- u_int16_t port; /* Port of the H.225 helper/RTCP/RTP channel */ +- enum ip_conntrack_dir dir; /* Direction of the original connection */ +- unsigned int offset; /* offset of the address in the payload */ +-}; +- +-/* This structure exists only once per master */ +-struct ip_ct_h225_master { +- int is_h225; /* H.225 or H.245 connection */ +-#ifdef CONFIG_IP_NF_NAT_NEEDED +- enum ip_conntrack_dir dir; /* Direction of the original connection */ +- u_int32_t seq[IP_CT_DIR_MAX]; /* Exceptional packet mangling for signal addressess... */ +- unsigned int offset[IP_CT_DIR_MAX]; /* ...and the offset of the addresses in the payload */ +-#endif +-}; +- +-#endif /* _IP_CONNTRACK_H323_H */ +diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_mms.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_mms.h +--- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_mms.h 2003-07-04 04:12:27.000000000 -0400 ++++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_mms.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,31 +0,0 @@ +-#ifndef _IP_CONNTRACK_MMS_H +-#define _IP_CONNTRACK_MMS_H +-/* MMS tracking. */ +- +-#ifdef __KERNEL__ +-#include +- +-DECLARE_LOCK_EXTERN(ip_mms_lock); +- +-#define MMS_PORT 1755 +-#define MMS_SRV_MSG_ID 196610 +- +-#define MMS_SRV_MSG_OFFSET 36 +-#define MMS_SRV_UNICODE_STRING_OFFSET 60 +-#define MMS_SRV_CHUNKLENLV_OFFSET 16 +-#define MMS_SRV_CHUNKLENLM_OFFSET 32 +-#define MMS_SRV_MESSAGELENGTH_OFFSET 8 +-#endif +- +-/* This structure is per expected connection */ +-struct ip_ct_mms_expect { +- u_int32_t len; +- u_int32_t padding; +- u_int16_t port; +-}; +- +-/* This structure exists only once per master */ +-struct ip_ct_mms_master { +-}; +- +-#endif /* _IP_CONNTRACK_MMS_H */ +diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_pptp.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_pptp.h +--- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_pptp.h 2003-07-04 04:12:27.000000000 -0400 ++++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_pptp.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,313 +0,0 @@ +-/* PPTP constants and structs */ +-#ifndef _CONNTRACK_PPTP_H +-#define _CONNTRACK_PPTP_H +- +-/* state of the control session */ +-enum pptp_ctrlsess_state { +- PPTP_SESSION_NONE, /* no session present */ +- PPTP_SESSION_ERROR, /* some session error */ +- PPTP_SESSION_STOPREQ, /* stop_sess request seen */ +- PPTP_SESSION_REQUESTED, /* start_sess request seen */ +- PPTP_SESSION_CONFIRMED, /* session established */ +-}; +- +-/* state of the call inside the control session */ +-enum pptp_ctrlcall_state { +- PPTP_CALL_NONE, +- PPTP_CALL_ERROR, +- PPTP_CALL_OUT_REQ, +- PPTP_CALL_OUT_CONF, +- PPTP_CALL_IN_REQ, +- PPTP_CALL_IN_REP, +- PPTP_CALL_IN_CONF, +- PPTP_CALL_CLEAR_REQ, +-}; +- +- +-/* conntrack private data */ +-struct ip_ct_pptp_master { +- enum pptp_ctrlsess_state sstate; /* session state */ +- +- /* everything below is going to be per-expectation in newnat, +- * since there could be more than one call within one session */ +- enum pptp_ctrlcall_state cstate; /* call state */ +- u_int16_t pac_call_id; /* call id of PAC, host byte order */ +- u_int16_t pns_call_id; /* call id of PNS, host byte order */ +-}; +- +-/* conntrack_expect private member */ +-struct ip_ct_pptp_expect { +- enum pptp_ctrlcall_state cstate; /* call state */ +- u_int16_t pac_call_id; /* call id of PAC */ +- u_int16_t pns_call_id; /* call id of PNS */ +-}; +- +- +-#ifdef __KERNEL__ +- +-#include +-DECLARE_LOCK_EXTERN(ip_pptp_lock); +- +-#define IP_CONNTR_PPTP PPTP_CONTROL_PORT +- +-union pptp_ctrl_union { +- void *rawreq; +- struct PptpStartSessionRequest *sreq; +- struct PptpStartSessionReply *srep; +- struct PptpStopSessionReqest *streq; +- struct PptpStopSessionReply *strep; +- struct PptpOutCallRequest *ocreq; +- struct PptpOutCallReply *ocack; +- struct PptpInCallRequest *icreq; +- struct PptpInCallReply *icack; +- struct PptpInCallConnected *iccon; +- struct PptpClearCallRequest *clrreq; +- struct PptpCallDisconnectNotify *disc; +- struct PptpWanErrorNotify *wanerr; +- struct PptpSetLinkInfo *setlink; +-}; +- +- +- +-#define PPTP_CONTROL_PORT 1723 +- +-#define PPTP_PACKET_CONTROL 1 +-#define PPTP_PACKET_MGMT 2 +- +-#define PPTP_MAGIC_COOKIE 0x1a2b3c4d +- +-struct pptp_pkt_hdr { +- __u16 packetLength; +- __u16 packetType; +- __u32 magicCookie; +-}; +- +-/* PptpControlMessageType values */ +-#define PPTP_START_SESSION_REQUEST 1 +-#define PPTP_START_SESSION_REPLY 2 +-#define PPTP_STOP_SESSION_REQUEST 3 +-#define PPTP_STOP_SESSION_REPLY 4 +-#define PPTP_ECHO_REQUEST 5 +-#define PPTP_ECHO_REPLY 6 +-#define PPTP_OUT_CALL_REQUEST 7 +-#define PPTP_OUT_CALL_REPLY 8 +-#define PPTP_IN_CALL_REQUEST 9 +-#define PPTP_IN_CALL_REPLY 10 +-#define PPTP_IN_CALL_CONNECT 11 +-#define PPTP_CALL_CLEAR_REQUEST 12 +-#define PPTP_CALL_DISCONNECT_NOTIFY 13 +-#define PPTP_WAN_ERROR_NOTIFY 14 +-#define PPTP_SET_LINK_INFO 15 +- +-#define PPTP_MSG_MAX 15 +- +-/* PptpGeneralError values */ +-#define PPTP_ERROR_CODE_NONE 0 +-#define PPTP_NOT_CONNECTED 1 +-#define PPTP_BAD_FORMAT 2 +-#define PPTP_BAD_VALUE 3 +-#define PPTP_NO_RESOURCE 4 +-#define PPTP_BAD_CALLID 5 +-#define PPTP_REMOVE_DEVICE_ERROR 6 +- +-struct PptpControlHeader { +- __u16 messageType; +- __u16 reserved; +-}; +- +-/* FramingCapability Bitmap Values */ +-#define PPTP_FRAME_CAP_ASYNC 0x1 +-#define PPTP_FRAME_CAP_SYNC 0x2 +- +-/* BearerCapability Bitmap Values */ +-#define PPTP_BEARER_CAP_ANALOG 0x1 +-#define PPTP_BEARER_CAP_DIGITAL 0x2 +- +-struct PptpStartSessionRequest { +- __u16 protocolVersion; +- __u8 reserved1; +- __u8 reserved2; +- __u32 framingCapability; +- __u32 bearerCapability; +- __u16 maxChannels; +- __u16 firmwareRevision; +- __u8 hostName[64]; +- __u8 vendorString[64]; +-}; +- +-/* PptpStartSessionResultCode Values */ +-#define PPTP_START_OK 1 +-#define PPTP_START_GENERAL_ERROR 2 +-#define PPTP_START_ALREADY_CONNECTED 3 +-#define PPTP_START_NOT_AUTHORIZED 4 +-#define PPTP_START_UNKNOWN_PROTOCOL 5 +- +-struct PptpStartSessionReply { +- __u16 protocolVersion; +- __u8 resultCode; +- __u8 generalErrorCode; +- __u32 framingCapability; +- __u32 bearerCapability; +- __u16 maxChannels; +- __u16 firmwareRevision; +- __u8 hostName[64]; +- __u8 vendorString[64]; +-}; +- +-/* PptpStopReasons */ +-#define PPTP_STOP_NONE 1 +-#define PPTP_STOP_PROTOCOL 2 +-#define PPTP_STOP_LOCAL_SHUTDOWN 3 +- +-struct PptpStopSessionRequest { +- __u8 reason; +-}; +- +-/* PptpStopSessionResultCode */ +-#define PPTP_STOP_OK 1 +-#define PPTP_STOP_GENERAL_ERROR 2 +- +-struct PptpStopSessionReply { +- __u8 resultCode; +- __u8 generalErrorCode; +-}; +- +-struct PptpEchoRequest { +- __u32 identNumber; +-}; +- +-/* PptpEchoReplyResultCode */ +-#define PPTP_ECHO_OK 1 +-#define PPTP_ECHO_GENERAL_ERROR 2 +- +-struct PptpEchoReply { +- __u32 identNumber; +- __u8 resultCode; +- __u8 generalErrorCode; +- __u16 reserved; +-}; +- +-/* PptpFramingType */ +-#define PPTP_ASYNC_FRAMING 1 +-#define PPTP_SYNC_FRAMING 2 +-#define PPTP_DONT_CARE_FRAMING 3 +- +-/* PptpCallBearerType */ +-#define PPTP_ANALOG_TYPE 1 +-#define PPTP_DIGITAL_TYPE 2 +-#define PPTP_DONT_CARE_BEARER_TYPE 3 +- +-struct PptpOutCallRequest { +- __u16 callID; +- __u16 callSerialNumber; +- __u32 minBPS; +- __u32 maxBPS; +- __u32 bearerType; +- __u32 framingType; +- __u16 packetWindow; +- __u16 packetProcDelay; +- __u16 reserved1; +- __u16 phoneNumberLength; +- __u16 reserved2; +- __u8 phoneNumber[64]; +- __u8 subAddress[64]; +-}; +- +-/* PptpCallResultCode */ +-#define PPTP_OUTCALL_CONNECT 1 +-#define PPTP_OUTCALL_GENERAL_ERROR 2 +-#define PPTP_OUTCALL_NO_CARRIER 3 +-#define PPTP_OUTCALL_BUSY 4 +-#define PPTP_OUTCALL_NO_DIAL_TONE 5 +-#define PPTP_OUTCALL_TIMEOUT 6 +-#define PPTP_OUTCALL_DONT_ACCEPT 7 +- +-struct PptpOutCallReply { +- __u16 callID; +- __u16 peersCallID; +- __u8 resultCode; +- __u8 generalErrorCode; +- __u16 causeCode; +- __u32 connectSpeed; +- __u16 packetWindow; +- __u16 packetProcDelay; +- __u32 physChannelID; +-}; +- +-struct PptpInCallRequest { +- __u16 callID; +- __u16 callSerialNumber; +- __u32 callBearerType; +- __u32 physChannelID; +- __u16 dialedNumberLength; +- __u16 dialingNumberLength; +- __u8 dialedNumber[64]; +- __u8 dialingNumber[64]; +- __u8 subAddress[64]; +-}; +- +-/* PptpInCallResultCode */ +-#define PPTP_INCALL_ACCEPT 1 +-#define PPTP_INCALL_GENERAL_ERROR 2 +-#define PPTP_INCALL_DONT_ACCEPT 3 +- +-struct PptpInCallReply { +- __u16 callID; +- __u16 peersCallID; +- __u8 resultCode; +- __u8 generalErrorCode; +- __u16 packetWindow; +- __u16 packetProcDelay; +- __u16 reserved; +-}; +- +-struct PptpInCallConnected { +- __u16 peersCallID; +- __u16 reserved; +- __u32 connectSpeed; +- __u16 packetWindow; +- __u16 packetProcDelay; +- __u32 callFramingType; +-}; +- +-struct PptpClearCallRequest { +- __u16 callID; +- __u16 reserved; +-}; +- +-struct PptpCallDisconnectNotify { +- __u16 callID; +- __u8 resultCode; +- __u8 generalErrorCode; +- __u16 causeCode; +- __u16 reserved; +- __u8 callStatistics[128]; +-}; +- +-struct PptpWanErrorNotify { +- __u16 peersCallID; +- __u16 reserved; +- __u32 crcErrors; +- __u32 framingErrors; +- __u32 hardwareOverRuns; +- __u32 bufferOverRuns; +- __u32 timeoutErrors; +- __u32 alignmentErrors; +-}; +- +-struct PptpSetLinkInfo { +- __u16 peersCallID; +- __u16 reserved; +- __u32 sendAccm; +- __u32 recvAccm; +-}; +- +- +-struct pptp_priv_data { +- __u16 call_id; +- __u16 mcall_id; +- __u16 pcall_id; +-}; +- +-#endif /* __KERNEL__ */ +-#endif /* _CONNTRACK_PPTP_H */ +diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h +--- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h 2003-07-04 04:12:27.000000000 -0400 ++++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_proto_gre.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,121 +0,0 @@ +-#ifndef _CONNTRACK_PROTO_GRE_H +-#define _CONNTRACK_PROTO_GRE_H +-#include +- +-/* GRE PROTOCOL HEADER */ +- +-/* GRE Version field */ +-#define GRE_VERSION_1701 0x0 +-#define GRE_VERSION_PPTP 0x1 +- +-/* GRE Protocol field */ +-#define GRE_PROTOCOL_PPTP 0x880B +- +-/* GRE Flags */ +-#define GRE_FLAG_C 0x80 +-#define GRE_FLAG_R 0x40 +-#define GRE_FLAG_K 0x20 +-#define GRE_FLAG_S 0x10 +-#define GRE_FLAG_A 0x80 +- +-#define GRE_IS_C(f) ((f)&GRE_FLAG_C) +-#define GRE_IS_R(f) ((f)&GRE_FLAG_R) +-#define GRE_IS_K(f) ((f)&GRE_FLAG_K) +-#define GRE_IS_S(f) ((f)&GRE_FLAG_S) +-#define GRE_IS_A(f) ((f)&GRE_FLAG_A) +- +-/* GRE is a mess: Four different standards */ +-struct gre_hdr { +-#if defined(__LITTLE_ENDIAN_BITFIELD) +- __u16 rec:3, +- srr:1, +- seq:1, +- key:1, +- routing:1, +- csum:1, +- version:3, +- reserved:4, +- ack:1; +-#elif defined(__BIG_ENDIAN_BITFIELD) +- __u16 csum:1, +- routing:1, +- key:1, +- seq:1, +- srr:1, +- rec:3, +- ack:1, +- reserved:4, +- version:3; +-#else +-#error "Adjust your defines" +-#endif +- __u16 protocol; +-}; +- +-/* modified GRE header for PPTP */ +-struct gre_hdr_pptp { +- __u8 flags; /* bitfield */ +- __u8 version; /* should be GRE_VERSION_PPTP */ +- __u16 protocol; /* should be GRE_PROTOCOL_PPTP */ +- __u16 payload_len; /* size of ppp payload, not inc. gre header */ +- __u16 call_id; /* peer's call_id for this session */ +- __u32 seq; /* sequence number. Present if S==1 */ +- __u32 ack; /* seq number of highest packet recieved by */ +- /* sender in this session */ +-}; +- +- +-/* this is part of ip_conntrack */ +-struct ip_ct_gre { +- unsigned int stream_timeout; +- unsigned int timeout; +-}; +- +-/* this is part of ip_conntrack_expect */ +-struct ip_ct_gre_expect { +- struct ip_ct_gre_keymap *keymap_orig, *keymap_reply; +-}; +- +-#ifdef __KERNEL__ +- +-/* structure for original <-> reply keymap */ +-struct ip_ct_gre_keymap { +- struct list_head list; +- +- struct ip_conntrack_tuple tuple; +- struct ip_conntrack_expect *master; +-}; +- +- +-/* add new tuple->key_reply pair to keymap */ +-int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp, +- struct ip_conntrack_tuple *t, +- int reply); +- +-/* change an existing keymap entry */ +-void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km, +- struct ip_conntrack_tuple *t); +- +- +- +-/* get pointer to gre key, if present */ +-static inline u_int32_t *gre_key(struct gre_hdr *greh) +-{ +- if (!greh->key) +- return NULL; +- if (greh->csum || greh->routing) +- return (u_int32_t *) (greh+sizeof(*greh)+4); +- return (u_int32_t *) (greh+sizeof(*greh)); +-} +- +-/* get pointer ot gre csum, if present */ +-static inline u_int16_t *gre_csum(struct gre_hdr *greh) +-{ +- if (!greh->csum) +- return NULL; +- return (u_int16_t *) (greh+sizeof(*greh)); +-} +- +-#endif /* __KERNEL__ */ +- +-#endif /* _CONNTRACK_PROTO_GRE_H */ +diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tftp.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tftp.h +--- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tftp.h 2003-07-04 04:12:27.000000000 -0400 ++++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tftp.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,13 +0,0 @@ +-#ifndef _IP_CT_TFTP +-#define _IP_CT_TFTP +- +-#define TFTP_PORT 69 +- +-struct tftphdr { +- u_int16_t opcode; +-}; +- +-#define TFTP_OPCODE_READ 1 +-#define TFTP_OPCODE_WRITE 2 +- +-#endif /* _IP_CT_TFTP */ +diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tuple.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tuple.h +--- src/linux/linux/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2003-07-04 04:12:27.000000000 -0400 ++++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_conntrack_tuple.h 2004-05-09 04:13:03.000000000 -0400 +@@ -14,7 +14,7 @@ + union ip_conntrack_manip_proto + { + /* Add other protocols here. */ +- u_int32_t all; ++ u_int16_t all; + + struct { + u_int16_t port; +@@ -25,9 +25,6 @@ + struct { + u_int16_t id; + } icmp; +- struct { +- u_int32_t key; +- } gre; + }; + + /* The manipulable part of the tuple. */ +@@ -47,7 +44,7 @@ + u_int32_t ip; + union { + /* Add other protocols here. */ +- u_int64_t all; ++ u_int16_t all; + + struct { + u_int16_t port; +@@ -58,11 +55,6 @@ + struct { + u_int8_t type, code; + } icmp; +- struct { +- u_int16_t protocol; +- u_int8_t version; +- u_int32_t key; +- } gre; + } u; + + /* The protocol. */ +@@ -80,16 +72,10 @@ + #ifdef __KERNEL__ + + #define DUMP_TUPLE(tp) \ +-DEBUGP("tuple %p: %u %u.%u.%u.%u:%u -> %u.%u.%u.%u:%u\n", \ ++DEBUGP("tuple %p: %u %u.%u.%u.%u:%hu -> %u.%u.%u.%u:%hu\n", \ + (tp), (tp)->dst.protonum, \ +- NIPQUAD((tp)->src.ip), ntohl((tp)->src.u.all), \ +- NIPQUAD((tp)->dst.ip), ntohl((tp)->dst.u.all)) +- +-#define DUMP_TUPLE_RAW(x) \ +- DEBUGP("tuple %p: %u %u.%u.%u.%u:0x%08x -> %u.%u.%u.%u:0x%08x\n",\ +- (x), (x)->dst.protonum, \ +- NIPQUAD((x)->src.ip), ntohl((x)->src.u.all), \ +- NIPQUAD((x)->dst.ip), ntohl((x)->dst.u.all)) ++ NIPQUAD((tp)->src.ip), ntohs((tp)->src.u.all), \ ++ NIPQUAD((tp)->dst.ip), ntohs((tp)->dst.u.all)) + + #define CTINFO2DIR(ctinfo) ((ctinfo) >= IP_CT_IS_REPLY ? IP_CT_DIR_REPLY : IP_CT_DIR_ORIGINAL) + +diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_nat_pptp.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_nat_pptp.h +--- src/linux/linux/include/linux/netfilter_ipv4/ip_nat_pptp.h 2003-07-04 04:12:27.000000000 -0400 ++++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_nat_pptp.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,11 +0,0 @@ +-/* PPTP constants and structs */ +-#ifndef _NAT_PPTP_H +-#define _NAT_PPTP_H +- +-/* conntrack private data */ +-struct ip_nat_pptp { +- u_int16_t pns_call_id; /* NAT'ed PNS call id */ +- u_int16_t pac_call_id; /* NAT'ed PAC call id */ +-}; +- +-#endif /* _NAT_PPTP_H */ +diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ip_pool.h src/linux/linux.stock/include/linux/netfilter_ipv4/ip_pool.h +--- src/linux/linux/include/linux/netfilter_ipv4/ip_pool.h 2003-07-04 04:12:27.000000000 -0400 ++++ src/linux/linux.stock/include/linux/netfilter_ipv4/ip_pool.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,64 +0,0 @@ +-#ifndef _IP_POOL_H +-#define _IP_POOL_H +- +-/***************************************************************************/ +-/* This program is free software; you can redistribute it and/or modify */ +-/* it under the terms of the GNU General Public License as published by */ +-/* the Free Software Foundation; either version 2 of the License, or */ +-/* (at your option) any later version. */ +-/* */ +-/* This program is distributed in the hope that it will be useful, */ +-/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +-/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ +-/* GNU General Public License for more details. */ +-/* */ +-/* You should have received a copy of the GNU General Public License */ +-/* along with this program; if not, write to the Free Software */ +-/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/ +-/***************************************************************************/ +- +-/* A sockopt of such quality has hardly ever been seen before on the open +- * market! This little beauty, hardly ever used: above 64, so it's +- * traditionally used for firewalling, not touched (even once!) by the +- * 2.0, 2.2 and 2.4 kernels! +- * +- * Comes with its own certificate of authenticity, valid anywhere in the +- * Free world! +- * +- * Rusty, 19.4.2000 +- */ +-#define SO_IP_POOL 81 +- +-typedef int ip_pool_t; /* pool index */ +-#define IP_POOL_NONE ((ip_pool_t)-1) +- +-struct ip_pool_request { +- int op; +- ip_pool_t index; +- u_int32_t addr; +- u_int32_t addr2; +-}; +- +-/* NOTE: I deliberately break the first cut ippool utility. Nobody uses it. */ +- +-#define IP_POOL_BAD001 0x00000010 +- +-#define IP_POOL_FLUSH 0x00000011 /* req.index, no arguments */ +-#define IP_POOL_INIT 0x00000012 /* from addr to addr2 incl. */ +-#define IP_POOL_DESTROY 0x00000013 /* req.index, no arguments */ +-#define IP_POOL_ADD_ADDR 0x00000014 /* add addr to pool */ +-#define IP_POOL_DEL_ADDR 0x00000015 /* del addr from pool */ +-#define IP_POOL_HIGH_NR 0x00000016 /* result in req.index */ +-#define IP_POOL_LOOKUP 0x00000017 /* result in addr and addr2 */ +-#define IP_POOL_USAGE 0x00000018 /* result in addr */ +-#define IP_POOL_TEST_ADDR 0x00000019 /* result (0/1) returned */ +- +-#ifdef __KERNEL__ +- +-/* NOTE: ip_pool_match() and ip_pool_mod() expect ADDR to be host byte order */ +-extern int ip_pool_match(ip_pool_t pool, u_int32_t addr); +-extern int ip_pool_mod(ip_pool_t pool, u_int32_t addr, int isdel); +- +-#endif +- +-#endif /*_IP_POOL_H*/ +diff -Nurb src/linux/linux/include/linux/netfilter_ipv4/ipt_pool.h src/linux/linux.stock/include/linux/netfilter_ipv4/ipt_pool.h +--- src/linux/linux/include/linux/netfilter_ipv4/ipt_pool.h 2003-07-04 04:12:27.000000000 -0400 ++++ src/linux/linux.stock/include/linux/netfilter_ipv4/ipt_pool.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,25 +0,0 @@ +-#ifndef _IPT_POOL_H +-#define _IPT_POOL_H +- +-#include +- +-#define IPT_POOL_INV_SRC 0x00000001 +-#define IPT_POOL_INV_DST 0x00000002 +-#define IPT_POOL_DEL_SRC 0x00000004 +-#define IPT_POOL_DEL_DST 0x00000008 +-#define IPT_POOL_INV_MOD_SRC 0x00000010 +-#define IPT_POOL_INV_MOD_DST 0x00000020 +-#define IPT_POOL_MOD_SRC_ACCEPT 0x00000040 +-#define IPT_POOL_MOD_DST_ACCEPT 0x00000080 +-#define IPT_POOL_MOD_SRC_DROP 0x00000100 +-#define IPT_POOL_MOD_DST_DROP 0x00000200 +- +-/* match info */ +-struct ipt_pool_info +-{ +- ip_pool_t src; +- ip_pool_t dst; +- unsigned flags; +-}; +- +-#endif /*_IPT_POOL_H*/ +diff -Nurb src/linux/linux/net/ipv4/netfilter/Config.in src/linux/linux.stock/net/ipv4/netfilter/Config.in +--- src/linux/linux/net/ipv4/netfilter/Config.in 2004-02-19 06:04:35.000000000 -0500 ++++ src/linux/linux.stock/net/ipv4/netfilter/Config.in 2004-05-09 04:13:03.000000000 -0400 +@@ -7,12 +7,7 @@ + tristate 'Connection tracking (required for masq/NAT)' CONFIG_IP_NF_CONNTRACK + if [ "$CONFIG_IP_NF_CONNTRACK" != "n" ]; then + dep_tristate ' FTP protocol support' CONFIG_IP_NF_FTP $CONFIG_IP_NF_CONNTRACK +- dep_tristate ' TFTP protocol support' CONFIG_IP_NF_TFTP $CONFIG_IP_NF_CONNTRACK +- dep_tristate ' H.323 (netmeeting) support' CONFIG_IP_NF_H323 $CONFIG_IP_NF_CONNTRACK + dep_tristate ' IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK +- dep_tristate ' MMS protocol support' CONFIG_IP_NF_MMS $CONFIG_IP_NF_CONNTRACK +- dep_tristate ' GRE protocol support' CONFIG_IP_NF_CT_PROTO_GRE $CONFIG_IP_NF_CONNTRACK +- dep_tristate ' PPTP protocol support' CONFIG_IP_NF_PPTP $CONFIG_IP_NF_CT_PROTO_GRE + fi + + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then +@@ -22,19 +17,11 @@ + if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then + # The simple matches. + dep_tristate ' limit match support' CONFIG_IP_NF_MATCH_LIMIT $CONFIG_IP_NF_IPTABLES +- +- dep_tristate ' IP address pool support' CONFIG_IP_NF_POOL $CONFIG_IP_NF_IPTABLES +- if [ "$CONFIG_IP_NF_POOL" = "y" -o "$CONFIG_IP_NF_POOL" = "m" ]; then +- bool ' enable statistics on pool usage' CONFIG_IP_POOL_STATISTICS n +- fi +- + dep_tristate ' MAC address match support' CONFIG_IP_NF_MATCH_MAC $CONFIG_IP_NF_IPTABLES + dep_tristate ' Packet type match support' CONFIG_IP_NF_MATCH_PKTTYPE $CONFIG_IP_NF_IPTABLES + dep_tristate ' netfilter MARK match support' CONFIG_IP_NF_MATCH_MARK $CONFIG_IP_NF_IPTABLES + dep_tristate ' Multiple port match support' CONFIG_IP_NF_MATCH_MULTIPORT $CONFIG_IP_NF_IPTABLES +- dep_tristate ' Multiple port with ranges match support' CONFIG_IP_NF_MATCH_MPORT $CONFIG_IP_NF_IPTABLES + dep_tristate ' TOS match support' CONFIG_IP_NF_MATCH_TOS $CONFIG_IP_NF_IPTABLES +- dep_tristate ' TIME match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_TIME $CONFIG_IP_NF_IPTABLES + dep_tristate ' ECN match support' CONFIG_IP_NF_MATCH_ECN $CONFIG_IP_NF_IPTABLES + + dep_tristate ' DSCP match support' CONFIG_IP_NF_MATCH_DSCP $CONFIG_IP_NF_IPTABLES +@@ -52,7 +39,6 @@ + fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Unclean match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_UNCLEAN $CONFIG_IP_NF_IPTABLES +- dep_tristate ' Webstr match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_WEBSTR $CONFIG_IP_NF_IPTABLES + dep_tristate ' Owner match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_OWNER $CONFIG_IP_NF_IPTABLES + fi + # The targets +@@ -70,29 +56,6 @@ + define_bool CONFIG_IP_NF_NAT_NEEDED y + dep_tristate ' MASQUERADE target support' CONFIG_IP_NF_TARGET_MASQUERADE $CONFIG_IP_NF_NAT + dep_tristate ' REDIRECT target support' CONFIG_IP_NF_TARGET_REDIRECT $CONFIG_IP_NF_NAT +- dep_tristate ' Automatic port forwarding (autofw) target support' CONFIG_IP_NF_AUTOFW $CONFIG_IP_NF_NAT +- dep_tristate ' TRIGGER target support (port-trigger)' CONFIG_IP_NF_TARGET_TRIGGER $CONFIG_IP_NF_NAT +- if [ "$CONFIG_IP_NF_H323" = "m" ]; then +- define_tristate CONFIG_IP_NF_NAT_H323 m +- else +- if [ "$CONFIG_IP_NF_H323" = "y" ]; then +- define_tristate CONFIG_IP_NF_NAT_H323 $CONFIG_IP_NF_NAT +- fi +- fi +- if [ "$CONFIG_IP_NF_PPTP" = "m" ]; then +- define_tristate CONFIG_IP_NF_NAT_PPTP m +- else +- if [ "$CONFIG_IP_NF_PPTP" = "y" ]; then +- define_tristate CONFIG_IP_NF_NAT_PPTP $CONFIG_IP_NF_NAT +- fi +- fi +- if [ "$CONFIG_IP_NF_CT_PROTO_GRE" = "m" ]; then +- define_tristate CONFIG_IP_NF_NAT_PROTO_GRE m +- else +- if [ "$CONFIG_IP_NF_CT_PROTO_GRE" = "y" ]; then +- define_tristate CONFIG_IP_NF_NAT_PROTO_GRE $CONFIG_IP_NF_NAT +- fi +- fi + bool ' NAT of local connections (READ HELP)' CONFIG_IP_NF_NAT_LOCAL + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + dep_tristate ' Basic SNMP-ALG support (EXPERIMENTAL)' CONFIG_IP_NF_NAT_SNMP_BASIC $CONFIG_IP_NF_NAT +@@ -104,13 +67,6 @@ + define_tristate CONFIG_IP_NF_NAT_IRC $CONFIG_IP_NF_NAT + fi + fi +- if [ "$CONFIG_IP_NF_MMS" = "m" ]; then +- define_tristate CONFIG_IP_NF_NAT_MMS m +- else +- if [ "$CONFIG_IP_NF_MMS" = "y" ]; then +- define_tristate CONFIG_IP_NF_NAT_MMS $CONFIG_IP_NF_NAT +- fi +- fi + # If they want FTP, set to $CONFIG_IP_NF_NAT (m or y), + # or $CONFIG_IP_NF_FTP (m or y), whichever is weaker. Argh. + if [ "$CONFIG_IP_NF_FTP" = "m" ]; then +@@ -120,13 +76,6 @@ + define_tristate CONFIG_IP_NF_NAT_FTP $CONFIG_IP_NF_NAT + fi + fi +- if [ "$CONFIG_IP_NF_TFTP" = "m" ]; then +- define_tristate CONFIG_IP_NF_NAT_TFTP m +- else +- if [ "$CONFIG_IP_NF_TFTP" = "y" ]; then +- define_tristate CONFIG_IP_NF_NAT_TFTP $CONFIG_IP_NF_NAT +- fi +- fi + fi + fi + +diff -Nurb src/linux/linux/net/ipv4/netfilter/Makefile src/linux/linux.stock/net/ipv4/netfilter/Makefile +--- src/linux/linux/net/ipv4/netfilter/Makefile 2004-02-19 06:04:35.000000000 -0500 ++++ src/linux/linux.stock/net/ipv4/netfilter/Makefile 2004-05-09 04:13:03.000000000 -0400 +@@ -31,48 +31,20 @@ + # connection tracking + obj-$(CONFIG_IP_NF_CONNTRACK) += ip_conntrack.o + +-# H.323 support +-obj-$(CONFIG_IP_NF_H323) += ip_conntrack_h323.o +-obj-$(CONFIG_IP_NF_NAT_H323) += ip_nat_h323.o +-ifdef CONFIG_IP_NF_NAT_H323 +- export-objs += ip_conntrack_h323.o +-endif +- +- +-# connection tracking protocol helpers +-obj-$(CONFIG_IP_NF_CT_PROTO_GRE) += ip_conntrack_proto_gre.o +-ifdef CONFIG_IP_NF_CT_PROTO_GRE +- export-objs += ip_conntrack_proto_gre.o +-endif +- +-# NAT protocol helpers +-obj-$(CONFIG_IP_NF_NAT_PROTO_GRE) += ip_nat_proto_gre.o +- + # connection tracking helpers +-obj-$(CONFIG_IP_NF_MMS) += ip_conntrack_mms.o +-ifdef CONFIG_IP_NF_NAT_MMS +- export-objs += ip_conntrack_mms.o +-endif +-obj-$(CONFIG_IP_NF_PPTP) += ip_conntrack_pptp.o +-ifdef CONFIG_IP_NF_NAT_PPTP +- export-objs += ip_conntrack_pptp.o +-endif +-obj-$(CONFIG_IP_NF_TFTP) += ip_conntrack_tftp.o + obj-$(CONFIG_IP_NF_FTP) += ip_conntrack_ftp.o + ifdef CONFIG_IP_NF_NAT_FTP + export-objs += ip_conntrack_ftp.o + endif ++ + obj-$(CONFIG_IP_NF_IRC) += ip_conntrack_irc.o + ifdef CONFIG_IP_NF_NAT_IRC + export-objs += ip_conntrack_irc.o + endif + + # NAT helpers +-obj-$(CONFIG_IP_NF_NAT_PPTP) += ip_nat_pptp.o +-obj-$(CONFIG_IP_NF_NAT_TFTP) += ip_nat_tftp.o + obj-$(CONFIG_IP_NF_NAT_FTP) += ip_nat_ftp.o + obj-$(CONFIG_IP_NF_NAT_IRC) += ip_nat_irc.o +-obj-$(CONFIG_IP_NF_NAT_MMS) += ip_nat_mms.o + + # generic IP tables + obj-$(CONFIG_IP_NF_IPTABLES) += ip_tables.o +@@ -86,19 +58,12 @@ + obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o + obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o + obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o +-obj-$(CONFIG_IP_NF_POOL) += ipt_pool.o ip_pool.o + obj-$(CONFIG_IP_NF_MATCH_MAC) += ipt_mac.o + + obj-$(CONFIG_IP_NF_MATCH_PKTTYPE) += ipt_pkttype.o + obj-$(CONFIG_IP_NF_MATCH_MULTIPORT) += ipt_multiport.o +- +-obj-$(CONFIG_IP_NF_MATCH_MPORT) += ipt_mport.o +- + obj-$(CONFIG_IP_NF_MATCH_OWNER) += ipt_owner.o + obj-$(CONFIG_IP_NF_MATCH_TOS) += ipt_tos.o +- +-obj-$(CONFIG_IP_NF_MATCH_TIME) += ipt_time.o +- + obj-$(CONFIG_IP_NF_MATCH_ECN) += ipt_ecn.o + obj-$(CONFIG_IP_NF_MATCH_DSCP) += ipt_dscp.o + obj-$(CONFIG_IP_NF_MATCH_AH_ESP) += ipt_ah.o ipt_esp.o +@@ -109,7 +74,6 @@ + obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o + obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o + obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o +-obj-$(CONFIG_IP_NF_MATCH_WEBSTR) += ipt_webstr.o + obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o + + # targets +@@ -125,8 +89,6 @@ + obj-$(CONFIG_IP_NF_TARGET_LOG) += ipt_LOG.o + obj-$(CONFIG_IP_NF_TARGET_ULOG) += ipt_ULOG.o + obj-$(CONFIG_IP_NF_TARGET_TCPMSS) += ipt_TCPMSS.o +-obj-$(CONFIG_IP_NF_AUTOFW) += ip_autofw.o +-obj-$(CONFIG_IP_NF_TARGET_TRIGGER) += ipt_TRIGGER.o + + # generic ARP tables + obj-$(CONFIG_IP_NF_ARPTABLES) += arp_tables.o +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_core.c +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_core.c 2003-08-12 07:33:45.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_core.c 2004-05-09 04:13:03.000000000 -0400 +@@ -47,7 +47,11 @@ + + #define IP_CONNTRACK_VERSION "2.1" + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + DECLARE_RWLOCK(ip_conntrack_lock); + DECLARE_RWLOCK(ip_conntrack_expect_tuple_lock); +@@ -62,29 +66,6 @@ + struct list_head *ip_conntrack_hash; + static kmem_cache_t *ip_conntrack_cachep; + +-#define SECS * HZ +-#define MINS * 60 SECS +-#define HOURS * 60 MINS +-#define DAYS * 24 HOURS +- +-int sysctl_ip_conntrack_tcp_timeouts[10] = { +- 30 MINS, /* TCP_CONNTRACK_NONE, */ +- 5 DAYS, /* TCP_CONNTRACK_ESTABLISHED, */ +- 2 MINS, /* TCP_CONNTRACK_SYN_SENT, */ +- 60 SECS, /* TCP_CONNTRACK_SYN_RECV, */ +- 2 MINS, /* TCP_CONNTRACK_FIN_WAIT, */ +- 2 MINS, /* TCP_CONNTRACK_TIME_WAIT, */ +- 10 SECS, /* TCP_CONNTRACK_CLOSE, */ +- 60 SECS, /* TCP_CONNTRACK_CLOSE_WAIT, */ +- 30 SECS, /* TCP_CONNTRACK_LAST_ACK, */ +- 2 MINS, /* TCP_CONNTRACK_LISTEN, */ +-}; +- +-int sysctl_ip_conntrack_udp_timeouts[2] = { +- 30 SECS, /* UNREPLIED */ +- 180 SECS /* ASSURED */ +-}; +- + extern struct ip_conntrack_protocol ip_conntrack_generic_protocol; + + static inline int proto_cmpfn(const struct ip_conntrack_protocol *curr, +@@ -129,6 +110,9 @@ + static inline u_int32_t + hash_conntrack(const struct ip_conntrack_tuple *tuple) + { ++#if 0 ++ dump_tuple(tuple); ++#endif + /* ntohl because more differences in low bits. */ + /* To ensure that halves of the same connection don't hash + clash, we add the source per-proto again. */ +@@ -160,8 +144,6 @@ + tuple->dst.ip = iph->daddr; + tuple->dst.protonum = iph->protocol; + +- tuple->src.u.all = tuple->dst.u.all = 0; +- + ret = protocol->pkt_to_tuple((u_int32_t *)iph + iph->ihl, + len - 4*iph->ihl, + tuple); +@@ -177,8 +159,6 @@ + inverse->dst.ip = orig->src.ip; + inverse->dst.protonum = orig->dst.protonum; + +- inverse->src.u.all = inverse->dst.u.all = 0; +- + return protocol->invert_tuple(inverse, orig); + } + +@@ -196,8 +176,8 @@ + static void + destroy_expect(struct ip_conntrack_expect *exp) + { +- DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use)); +- IP_NF_ASSERT(atomic_read(&exp->use)); ++ DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(exp->use)); ++ IP_NF_ASSERT(atomic_read(exp->use)); + IP_NF_ASSERT(!timer_pending(&exp->timeout)); + + kfree(exp); +@@ -267,11 +247,11 @@ + static void unexpect_related(struct ip_conntrack_expect *expect) + { + IP_NF_ASSERT(expect->expectant); ++ IP_NF_ASSERT(expect->expectant->helper); + /* if we are supposed to have a timer, but we can't delete + * it: race condition. __unexpect_related will + * be calledd by timeout function */ +- if (expect->expectant->helper +- && expect->expectant->helper->timeout ++ if (expect->expectant->helper->timeout + && !del_timer(&expect->timeout)) + return; + +@@ -580,6 +560,7 @@ + if (!h) { + /* Locally generated ICMPs will match inverted if they + haven't been SNAT'ed yet */ ++ /* FIXME: NAT code has to handle half-done double NAT --RR */ + if (hooknum == NF_IP_LOCAL_OUT) + h = ip_conntrack_find_get(&origtuple, NULL); + +@@ -725,7 +706,6 @@ + + /* If the expectation is dying, then this is a looser. */ + if (expected +- && expected->expectant->helper + && expected->expectant->helper->timeout + && ! del_timer(&expected->timeout)) + expected = NULL; +@@ -744,7 +724,6 @@ + conntrack->master = expected; + expected->sibling = conntrack; + LIST_DELETE(&ip_conntrack_expect_list, expected); +- INIT_LIST_HEAD(&expected->list); + expected->expectant->expecting--; + nf_conntrack_get(&master_ct(conntrack)->infos[0]); + } +@@ -821,9 +800,23 @@ + int set_reply; + int ret; + ++ /* FIXME: Do this right please. --RR */ + (*pskb)->nfcache |= NFC_UNKNOWN; + + /* Doesn't cover locally-generated broadcast, so not worth it. */ ++#if 0 ++ /* Ignore broadcast: no `connection'. */ ++ if ((*pskb)->pkt_type == PACKET_BROADCAST) { ++ printk("Broadcast packet!\n"); ++ return NF_ACCEPT; ++ } else if (((*pskb)->nh.iph->daddr & htonl(0x000000FF)) ++ == htonl(0x000000FF)) { ++ printk("Should bcast: %u.%u.%u.%u->%u.%u.%u.%u (sk=%p, ptype=%u)\n", ++ NIPQUAD((*pskb)->nh.iph->saddr), ++ NIPQUAD((*pskb)->nh.iph->daddr), ++ (*pskb)->sk, (*pskb)->pkt_type); ++ } ++#endif + + /* Previously seen (loopback)? Ignore. Do this before + fragment check. */ +@@ -943,8 +936,8 @@ + * so there is no need to use the tuple lock too */ + + DEBUGP("ip_conntrack_expect_related %p\n", related_to); +- DEBUGP("tuple: "); DUMP_TUPLE_RAW(&expect->tuple); +- DEBUGP("mask: "); DUMP_TUPLE_RAW(&expect->mask); ++ DEBUGP("tuple: "); DUMP_TUPLE(&expect->tuple); ++ DEBUGP("mask: "); DUMP_TUPLE(&expect->mask); + + old = LIST_FIND(&ip_conntrack_expect_list, resent_expect, + struct ip_conntrack_expect *, &expect->tuple, +@@ -954,8 +947,7 @@ + pointing into the payload - otherwise we should have to copy + the data filled out by the helper over the old one */ + DEBUGP("expect_related: resent packet\n"); +- if (related_to->helper && +- related_to->helper->timeout) { ++ if (related_to->helper->timeout) { + if (!del_timer(&old->timeout)) { + /* expectation is dying. Fall through */ + old = NULL; +@@ -970,32 +962,26 @@ + WRITE_UNLOCK(&ip_conntrack_lock); + return -EEXIST; + } +- } else if (related_to->helper && +- related_to->helper->max_expected && ++ } else if (related_to->helper->max_expected && + related_to->expecting >= related_to->helper->max_expected) { + struct list_head *cur_item; + /* old == NULL */ +- if (!(related_to->helper->flags & +- IP_CT_HELPER_F_REUSE_EXPECT)) { +- WRITE_UNLOCK(&ip_conntrack_lock); + if (net_ratelimit()) + printk(KERN_WARNING + "ip_conntrack: max number of expected " + "connections %i of %s reached for " +- "%u.%u.%u.%u->%u.%u.%u.%u\n", ++ "%u.%u.%u.%u->%u.%u.%u.%u%s\n", + related_to->helper->max_expected, + related_to->helper->name, + NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), +- NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); ++ NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip), ++ related_to->helper->flags & IP_CT_HELPER_F_REUSE_EXPECT ? ++ ", reusing" : ""); ++ if (!(related_to->helper->flags & ++ IP_CT_HELPER_F_REUSE_EXPECT)) { ++ WRITE_UNLOCK(&ip_conntrack_lock); + return -EPERM; + } +- DEBUGP("ip_conntrack: max number of expected " +- "connections %i of %s reached for " +- "%u.%u.%u.%u->%u.%u.%u.%u, reusing\n", +- related_to->helper->max_expected, +- related_to->helper->name, +- NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip), +- NIPQUAD(related_to->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip)); + + /* choose the the oldest expectation to evict */ + list_for_each(cur_item, &related_to->sibling_list) { +@@ -1055,8 +1041,7 @@ + /* add to global list of expectations */ + list_prepend(&ip_conntrack_expect_list, &new->list); + /* add and start timer if required */ +- if (related_to->helper && +- related_to->helper->timeout) { ++ if (related_to->helper->timeout) { + init_timer(&new->timeout); + new->timeout.data = (unsigned long)new; + new->timeout.function = expectation_timed_out; +@@ -1079,10 +1064,11 @@ + + MUST_BE_READ_LOCKED(&ip_conntrack_lock); + WRITE_LOCK(&ip_conntrack_expect_tuple_lock); ++ + DEBUGP("change_expect:\n"); +- DEBUGP("exp tuple: "); DUMP_TUPLE_RAW(&expect->tuple); +- DEBUGP("exp mask: "); DUMP_TUPLE_RAW(&expect->mask); +- DEBUGP("newtuple: "); DUMP_TUPLE_RAW(newtuple); ++ DEBUGP("exp tuple: "); DUMP_TUPLE(&expect->tuple); ++ DEBUGP("exp mask: "); DUMP_TUPLE(&expect->mask); ++ DEBUGP("newtuple: "); DUMP_TUPLE(newtuple); + if (expect->ct_tuple.dst.protonum == 0) { + /* Never seen before */ + DEBUGP("change expect: never seen before\n"); +@@ -1360,8 +1346,6 @@ + 0, NULL }; + + #define NET_IP_CONNTRACK_MAX 2089 +-#define NET_IP_CONNTRACK_TCP_TIMEOUTS 2090 +-#define NET_IP_CONNTRACK_UDP_TIMEOUTS 2091 + #define NET_IP_CONNTRACK_MAX_NAME "ip_conntrack_max" + + #ifdef CONFIG_SYSCTL +@@ -1370,14 +1354,6 @@ + static ctl_table ip_conntrack_table[] = { + { NET_IP_CONNTRACK_MAX, NET_IP_CONNTRACK_MAX_NAME, &ip_conntrack_max, + sizeof(ip_conntrack_max), 0644, NULL, proc_dointvec }, +- { NET_IP_CONNTRACK_TCP_TIMEOUTS, "ip_conntrack_tcp_timeouts", +- &sysctl_ip_conntrack_tcp_timeouts, +- sizeof(sysctl_ip_conntrack_tcp_timeouts), +- 0644, NULL, &proc_dointvec_jiffies, &sysctl_jiffies }, +- { NET_IP_CONNTRACK_UDP_TIMEOUTS, "ip_conntrack_udp_timeouts", +- &sysctl_ip_conntrack_udp_timeouts, +- sizeof(sysctl_ip_conntrack_udp_timeouts), +- 0644, NULL, &proc_dointvec_jiffies, &sysctl_jiffies }, + { 0 } + }; + +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_ftp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_ftp.c +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_ftp.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_ftp.c 2004-05-09 04:13:03.000000000 -0400 +@@ -24,7 +24,11 @@ + static int loose = 0; + MODULE_PARM(loose, "i"); + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + static int try_rfc959(const char *, size_t, u_int32_t [], char); + static int try_eprt(const char *, size_t, u_int32_t [], char); +@@ -191,6 +195,16 @@ + } + + if (strnicmp(data, pattern, plen) != 0) { ++#if 0 ++ size_t i; ++ ++ DEBUGP("ftp: string mismatch\n"); ++ for (i = 0; i < plen; i++) { ++ DEBUGFTP("ftp:char %u `%c'(%u) vs `%c'(%u)\n", ++ i, data[i], data[i], ++ pattern[i], pattern[i]); ++ } ++#endif + return 0; + } + +@@ -214,6 +228,7 @@ + return 1; + } + ++/* FIXME: This should be in userspace. Later. */ + static int help(const struct iphdr *iph, size_t len, + struct ip_conntrack *ct, + enum ip_conntrack_info ctinfo) +@@ -249,6 +264,7 @@ + } + + /* Checksum invalid? Ignore. */ ++ /* FIXME: Source route IP option packets --RR */ + if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, + csum_partial((char *)tcph, tcplen, 0))) { + DEBUGP("ftp_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_h323.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_h323.c +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_h323.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_h323.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,302 +0,0 @@ +-/* +- * H.323 'brute force' extension for H.323 connection tracking. +- * Jozsef Kadlecsik +- * +- * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project. +- * (http://www.coritel.it/projects/sofia/nat/) +- * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind' +- * the unregistered helpers to the conntrack entries. +- */ +- +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-MODULE_AUTHOR("Jozsef Kadlecsik "); +-MODULE_DESCRIPTION("H.323 'brute force' connection tracking module"); +-MODULE_LICENSE("GPL"); +- +-DECLARE_LOCK(ip_h323_lock); +-struct module *ip_conntrack_h323 = THIS_MODULE; +- +-#define DEBUGP(format, args...) +- +-static int h245_help(const struct iphdr *iph, size_t len, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- struct tcphdr *tcph = (void *)iph + iph->ihl * 4; +- unsigned char *data = (unsigned char *) tcph + tcph->doff * 4; +- unsigned char *data_limit; +- u_int32_t tcplen = len - iph->ihl * 4; +- u_int32_t datalen = tcplen - tcph->doff * 4; +- int dir = CTINFO2DIR(ctinfo); +- struct ip_ct_h225_master *info = &ct->help.ct_h225_info; +- struct ip_conntrack_expect expect, *exp = &expect; +- struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info; +- u_int16_t data_port; +- u_int32_t data_ip; +- unsigned int i; +- +- DEBUGP("ct_h245_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n", +- NIPQUAD(iph->saddr), ntohs(tcph->source), +- NIPQUAD(iph->daddr), ntohs(tcph->dest)); +- +- /* Can't track connections formed before we registered */ +- if (!info) +- return NF_ACCEPT; +- +- /* Until there's been traffic both ways, don't look in packets. */ +- if (ctinfo != IP_CT_ESTABLISHED +- && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { +- DEBUGP("ct_h245_help: Conntrackinfo = %u\n", ctinfo); +- return NF_ACCEPT; +- } +- +- /* Not whole TCP header or too short packet? */ +- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) { +- DEBUGP("ct_h245_help: tcplen = %u\n", (unsigned)tcplen); +- return NF_ACCEPT; +- } +- +- /* Checksum invalid? Ignore. */ +- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, +- csum_partial((char *)tcph, tcplen, 0))) { +- DEBUGP("ct_h245_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", +- tcph, tcplen, NIPQUAD(iph->saddr), +- NIPQUAD(iph->daddr)); +- return NF_ACCEPT; +- } +- +- data_limit = (unsigned char *) data + datalen; +- /* bytes: 0123 45 +- ipadrr port */ +- for (i = 0; data < (data_limit - 5); data++, i++) { +- memcpy(&data_ip, data, sizeof(u_int32_t)); +- if (data_ip == iph->saddr) { +- memcpy(&data_port, data + 4, sizeof(u_int16_t)); +- memset(&expect, 0, sizeof(expect)); +- /* update the H.225 info */ +- DEBUGP("ct_h245_help: new RTCP/RTP requested %u.%u.%u.%u:->%u.%u.%u.%u:%u\n", +- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), +- NIPQUAD(iph->saddr), ntohs(data_port)); +- LOCK_BH(&ip_h323_lock); +- info->is_h225 = H225_PORT + 1; +- exp_info->port = data_port; +- exp_info->dir = dir; +- exp_info->offset = i; +- +- exp->seq = ntohl(tcph->seq) + i; +- +- exp->tuple = ((struct ip_conntrack_tuple) +- { { ct->tuplehash[!dir].tuple.src.ip, +- { 0 } }, +- { data_ip, +- { data_port }, +- IPPROTO_UDP }}); +- exp->mask = ((struct ip_conntrack_tuple) +- { { 0xFFFFFFFF, { 0 } }, +- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); +- +- exp->expectfn = NULL; +- +- /* Ignore failure; should only happen with NAT */ +- ip_conntrack_expect_related(ct, exp); +- +- UNLOCK_BH(&ip_h323_lock); +- } +- } +- +- return NF_ACCEPT; +- +-} +- +-/* H.245 helper is not registered! */ +-static struct ip_conntrack_helper h245 = +- { { NULL, NULL }, +- "H.245", /* name */ +- IP_CT_HELPER_F_REUSE_EXPECT, /* flags */ +- NULL, /* module */ +- 8, /* max_ expected */ +- 240, /* timeout */ +- { { 0, { 0 } }, /* tuple */ +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { 0xFFFF } }, /* mask */ +- { 0, { 0 }, 0xFFFF } }, +- h245_help /* helper */ +- }; +- +-static int h225_expect(struct ip_conntrack *ct) +-{ +- WRITE_LOCK(&ip_conntrack_lock); +- ct->helper = &h245; +- DEBUGP("h225_expect: helper for %p added\n", ct); +- WRITE_UNLOCK(&ip_conntrack_lock); +- +- return NF_ACCEPT; /* unused */ +-} +- +-static int h225_help(const struct iphdr *iph, size_t len, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- struct tcphdr *tcph = (void *)iph + iph->ihl * 4; +- unsigned char *data = (unsigned char *) tcph + tcph->doff * 4; +- unsigned char *data_limit; +- u_int32_t tcplen = len - iph->ihl * 4; +- u_int32_t datalen = tcplen - tcph->doff * 4; +- int dir = CTINFO2DIR(ctinfo); +- struct ip_ct_h225_master *info = &ct->help.ct_h225_info; +- struct ip_conntrack_expect expect, *exp = &expect; +- struct ip_ct_h225_expect *exp_info = &exp->help.exp_h225_info; +- u_int16_t data_port; +- u_int32_t data_ip; +- unsigned int i; +- +- DEBUGP("ct_h225_help: help entered %u.%u.%u.%u:%u->%u.%u.%u.%u:%u\n", +- NIPQUAD(iph->saddr), ntohs(tcph->source), +- NIPQUAD(iph->daddr), ntohs(tcph->dest)); +- +- /* Can't track connections formed before we registered */ +- if (!info) +- return NF_ACCEPT; +- +- /* Until there's been traffic both ways, don't look in packets. */ +- if (ctinfo != IP_CT_ESTABLISHED +- && ctinfo != IP_CT_ESTABLISHED + IP_CT_IS_REPLY) { +- DEBUGP("ct_h225_help: Conntrackinfo = %u\n", ctinfo); +- return NF_ACCEPT; +- } +- +- /* Not whole TCP header or too short packet? */ +- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4 + 5) { +- DEBUGP("ct_h225_help: tcplen = %u\n", (unsigned)tcplen); +- return NF_ACCEPT; +- } +- +- /* Checksum invalid? Ignore. */ +- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, +- csum_partial((char *)tcph, tcplen, 0))) { +- DEBUGP("ct_h225_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", +- tcph, tcplen, NIPQUAD(iph->saddr), +- NIPQUAD(iph->daddr)); +- return NF_ACCEPT; +- } +- +- data_limit = (unsigned char *) data + datalen; +- /* bytes: 0123 45 +- ipadrr port */ +- for (i = 0; data < (data_limit - 5); data++, i++) { +- memcpy(&data_ip, data, sizeof(u_int32_t)); +- if (data_ip == iph->saddr) { +- memcpy(&data_port, data + 4, sizeof(u_int16_t)); +- if (data_port == tcph->source) { +- /* Signal address */ +- DEBUGP("ct_h225_help: sourceCallSignalAddress from %u.%u.%u.%u\n", +- NIPQUAD(iph->saddr)); +- /* Update the H.225 info so that NAT can mangle the address/port +- even when we have no expected connection! */ +-#ifdef CONFIG_IP_NF_NAT_NEEDED +- LOCK_BH(&ip_h323_lock); +- info->dir = dir; +- info->seq[IP_CT_DIR_ORIGINAL] = ntohl(tcph->seq) + i; +- info->offset[IP_CT_DIR_ORIGINAL] = i; +- UNLOCK_BH(&ip_h323_lock); +-#endif +- } else { +- memset(&expect, 0, sizeof(expect)); +- +- /* update the H.225 info */ +- LOCK_BH(&ip_h323_lock); +- info->is_h225 = H225_PORT; +- exp_info->port = data_port; +- exp_info->dir = dir; +- exp_info->offset = i; +- +- exp->seq = ntohl(tcph->seq) + i; +- +- exp->tuple = ((struct ip_conntrack_tuple) +- { { ct->tuplehash[!dir].tuple.src.ip, +- { 0 } }, +- { data_ip, +- { data_port }, +- IPPROTO_TCP }}); +- exp->mask = ((struct ip_conntrack_tuple) +- { { 0xFFFFFFFF, { 0 } }, +- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); +- +- exp->expectfn = h225_expect; +- +- /* Ignore failure */ +- ip_conntrack_expect_related(ct, exp); +- +- DEBUGP("ct_h225_help: new H.245 requested %u.%u.%u.%u->%u.%u.%u.%u:%u\n", +- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), +- NIPQUAD(iph->saddr), ntohs(data_port)); +- +- UNLOCK_BH(&ip_h323_lock); +- } +-#ifdef CONFIG_IP_NF_NAT_NEEDED +- } else if (data_ip == iph->daddr) { +- memcpy(&data_port, data + 4, sizeof(u_int16_t)); +- if (data_port == tcph->dest) { +- /* Signal address */ +- DEBUGP("ct_h225_help: destCallSignalAddress %u.%u.%u.%u\n", +- NIPQUAD(iph->daddr)); +- /* Update the H.225 info so that NAT can mangle the address/port +- even when we have no expected connection! */ +- LOCK_BH(&ip_h323_lock); +- info->dir = dir; +- info->seq[IP_CT_DIR_REPLY] = ntohl(tcph->seq) + i; +- info->offset[IP_CT_DIR_REPLY] = i; +- UNLOCK_BH(&ip_h323_lock); +- } +-#endif +- } +- } +- +- return NF_ACCEPT; +- +-} +- +-static struct ip_conntrack_helper h225 = +- { { NULL, NULL }, +- "H.225", /* name */ +- IP_CT_HELPER_F_REUSE_EXPECT, /* flags */ +- THIS_MODULE, /* module */ +- 2, /* max_expected */ +- 240, /* timeout */ +- { { 0, { __constant_htons(H225_PORT) } }, /* tuple */ +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { 0xFFFF } }, /* mask */ +- { 0, { 0 }, 0xFFFF } }, +- h225_help /* helper */ +- }; +- +-static int __init init(void) +-{ +- return ip_conntrack_helper_register(&h225); +-} +- +-static void __exit fini(void) +-{ +- /* Unregister H.225 helper */ +- ip_conntrack_helper_unregister(&h225); +-} +- +-#ifdef CONFIG_IP_NF_NAT_NEEDED +-EXPORT_SYMBOL(ip_h323_lock); +-#endif +- +-module_init(init); +-module_exit(fini); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_mms.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_mms.c +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_mms.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_mms.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,292 +0,0 @@ +-/* MMS extension for IP connection tracking +- * (C) 2002 by Filip Sneppe +- * based on ip_conntrack_ftp.c and ip_conntrack_irc.c +- * +- * ip_conntrack_mms.c v0.3 2002-09-22 +- * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License +- * as published by the Free Software Foundation; either version +- * 2 of the License, or (at your option) any later version. +- * +- * Module load syntax: +- * insmod ip_conntrack_mms.o ports=port1,port2,...port +- * +- * Please give the ports of all MMS servers You wish to connect to. +- * If you don't specify ports, the default will be TCP port 1755. +- * +- * More info on MMS protocol, firewalls and NAT: +- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp +- * http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp +- * +- * The SDP project people are reverse-engineering MMS: +- * http://get.to/sdp +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-DECLARE_LOCK(ip_mms_lock); +-struct module *ip_conntrack_mms = THIS_MODULE; +- +-#define MAX_PORTS 8 +-static int ports[MAX_PORTS]; +-static int ports_c; +-#ifdef MODULE_PARM +-MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); +-#endif +- +-#define DEBUGP(format, args...) +- +-#ifdef CONFIG_IP_NF_NAT_NEEDED +-EXPORT_SYMBOL(ip_mms_lock); +-#endif +- +-MODULE_AUTHOR("Filip Sneppe "); +-MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) connection tracking module"); +-MODULE_LICENSE("GPL"); +- +-/* #define isdigit(c) (c >= '0' && c <= '9') */ +- +-/* copied from drivers/usb/serial/io_edgeport.c - not perfect but will do the trick */ +-static void unicode_to_ascii (char *string, short *unicode, int unicode_size) +-{ +- int i; +- for (i = 0; i < unicode_size; ++i) { +- string[i] = (char)(unicode[i]); +- } +- string[unicode_size] = 0x00; +-} +- +-__inline static int atoi(char *s) +-{ +- int i=0; +- while (isdigit(*s)) { +- i = i*10 + *(s++) - '0'; +- } +- return i; +-} +- +-/* convert ip address string like "192.168.0.10" to unsigned int */ +-__inline static u_int32_t asciiiptoi(char *s) +-{ +- unsigned int i, j, k; +- +- for(i=k=0; k<3; ++k, ++s, i<<=8) { +- i+=atoi(s); +- for(j=0; (*(++s) != '.') && (j<3); ++j) +- ; +- } +- i+=atoi(s); +- return ntohl(i); +-} +- +-int parse_mms(const char *data, +- const unsigned int datalen, +- u_int32_t *mms_ip, +- u_int16_t *mms_proto, +- u_int16_t *mms_port, +- char **mms_string_b, +- char **mms_string_e, +- char **mms_padding_e) +-{ +- int unicode_size, i; +- char tempstring[28]; /* "\\255.255.255.255\UDP\65535" */ +- char getlengthstring[28]; +- +- for(unicode_size=0; +- (char) *(data+(MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2)) != (char)0; +- unicode_size++) +- if ((unicode_size == 28) || (MMS_SRV_UNICODE_STRING_OFFSET+unicode_size*2 >= datalen)) +- return -1; /* out of bounds - incomplete packet */ +- +- unicode_to_ascii(tempstring, (short *)(data+MMS_SRV_UNICODE_STRING_OFFSET), unicode_size); +- DEBUGP("ip_conntrack_mms: offset 60: %s\n", (const char *)(tempstring)); +- +- /* IP address ? */ +- *mms_ip = asciiiptoi(tempstring+2); +- +- i=sprintf(getlengthstring, "%u.%u.%u.%u", HIPQUAD(*mms_ip)); +- +- /* protocol ? */ +- if(strncmp(tempstring+3+i, "TCP", 3)==0) +- *mms_proto = IPPROTO_TCP; +- else if(strncmp(tempstring+3+i, "UDP", 3)==0) +- *mms_proto = IPPROTO_UDP; +- +- /* port ? */ +- *mms_port = atoi(tempstring+7+i); +- +- /* we store a pointer to the beginning of the "\\a.b.c.d\proto\port" +- unicode string, one to the end of the string, and one to the end +- of the packet, since we must keep track of the number of bytes +- between end of the unicode string and the end of packet (padding) */ +- *mms_string_b = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET); +- *mms_string_e = (char *)(data + MMS_SRV_UNICODE_STRING_OFFSET + unicode_size * 2); +- *mms_padding_e = (char *)(data + datalen); /* looks funny, doesn't it */ +- return 0; +-} +- +- +-static int help(const struct iphdr *iph, size_t len, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- /* tcplen not negative guaranteed by ip_conntrack_tcp.c */ +- struct tcphdr *tcph = (void *)iph + iph->ihl * 4; +- const char *data = (const char *)tcph + tcph->doff * 4; +- unsigned int tcplen = len - iph->ihl * 4; +- unsigned int datalen = tcplen - tcph->doff * 4; +- int dir = CTINFO2DIR(ctinfo); +- struct ip_conntrack_expect expect, *exp = &expect; +- struct ip_ct_mms_expect *exp_mms_info = &exp->help.exp_mms_info; +- +- u_int32_t mms_ip; +- u_int16_t mms_proto; +- char mms_proto_string[8]; +- u_int16_t mms_port; +- char *mms_string_b, *mms_string_e, *mms_padding_e; +- +- /* Until there's been traffic both ways, don't look in packets. */ +- if (ctinfo != IP_CT_ESTABLISHED +- && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) { +- DEBUGP("ip_conntrack_mms: Conntrackinfo = %u\n", ctinfo); +- return NF_ACCEPT; +- } +- +- /* Not whole TCP header? */ +- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff*4) { +- DEBUGP("ip_conntrack_mms: tcplen = %u\n", (unsigned)tcplen); +- return NF_ACCEPT; +- } +- +- /* Checksum invalid? Ignore. */ +- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, +- csum_partial((char *)tcph, tcplen, 0))) { +- DEBUGP("mms_help: bad csum: %p %u %u.%u.%u.%u %u.%u.%u.%u\n", +- tcph, tcplen, NIPQUAD(iph->saddr), +- NIPQUAD(iph->daddr)); +- return NF_ACCEPT; +- } +- +- /* Only look at packets with 0x00030002/196610 on bytes 36->39 of TCP payload */ +- if( (MMS_SRV_MSG_OFFSET < datalen) && +- ((*(u32 *)(data+MMS_SRV_MSG_OFFSET)) == MMS_SRV_MSG_ID)) { +- DEBUGP("ip_conntrack_mms: offset 37: %u %u %u %u, datalen:%u\n", +- (u8)*(data+36), (u8)*(data+37), +- (u8)*(data+38), (u8)*(data+39), +- datalen); +- if(parse_mms(data, datalen, &mms_ip, &mms_proto, &mms_port, +- &mms_string_b, &mms_string_e, &mms_padding_e)) +- if(net_ratelimit()) +- printk(KERN_WARNING +- "ip_conntrack_mms: Unable to parse data payload\n"); +- +- memset(&expect, 0, sizeof(expect)); +- +- sprintf(mms_proto_string, "(%u)", mms_proto); +- DEBUGP("ip_conntrack_mms: adding %s expectation %u.%u.%u.%u -> %u.%u.%u.%u:%u\n", +- mms_proto == IPPROTO_TCP ? "TCP" +- : mms_proto == IPPROTO_UDP ? "UDP":mms_proto_string, +- NIPQUAD(ct->tuplehash[!dir].tuple.src.ip), +- NIPQUAD(mms_ip), +- mms_port); +- +- /* it's possible that the client will just ask the server to tunnel +- the stream over the same TCP session (from port 1755): there's +- shouldn't be a need to add an expectation in that case, but it +- makes NAT packet mangling so much easier */ +- LOCK_BH(&ip_mms_lock); +- +- DEBUGP("ip_conntrack_mms: tcph->seq = %u\n", tcph->seq); +- +- exp->seq = ntohl(tcph->seq) + (mms_string_b - data); +- exp_mms_info->len = (mms_string_e - mms_string_b); +- exp_mms_info->padding = (mms_padding_e - mms_string_e); +- exp_mms_info->port = mms_port; +- +- DEBUGP("ip_conntrack_mms: wrote info seq=%u (ofs=%u), len=%d, padding=%u\n", +- exp->seq, (mms_string_e - data), exp_mms_info->len, exp_mms_info->padding); +- +- exp->tuple = ((struct ip_conntrack_tuple) +- { { ct->tuplehash[!dir].tuple.src.ip, { 0 } }, +- { mms_ip, +- { (__u16) ntohs(mms_port) }, +- mms_proto } } +- ); +- exp->mask = ((struct ip_conntrack_tuple) +- { { 0xFFFFFFFF, { 0 } }, +- { 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); +- exp->expectfn = NULL; +- ip_conntrack_expect_related(ct, &expect); +- UNLOCK_BH(&ip_mms_lock); +- } +- +- return NF_ACCEPT; +-} +- +-static struct ip_conntrack_helper mms[MAX_PORTS]; +-static char mms_names[MAX_PORTS][10]; +- +-/* Not __exit: called from init() */ +-static void fini(void) +-{ +- int i; +- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { +- DEBUGP("ip_conntrack_mms: unregistering helper for port %d\n", +- ports[i]); +- ip_conntrack_helper_unregister(&mms[i]); +- } +-} +- +-static int __init init(void) +-{ +- int i, ret; +- char *tmpname; +- +- if (ports[0] == 0) +- ports[0] = MMS_PORT; +- +- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { +- memset(&mms[i], 0, sizeof(struct ip_conntrack_helper)); +- mms[i].tuple.src.u.tcp.port = htons(ports[i]); +- mms[i].tuple.dst.protonum = IPPROTO_TCP; +- mms[i].mask.src.u.tcp.port = 0xFFFF; +- mms[i].mask.dst.protonum = 0xFFFF; +- mms[i].max_expected = 1; +- mms[i].timeout = 0; +- mms[i].flags = IP_CT_HELPER_F_REUSE_EXPECT; +- mms[i].me = THIS_MODULE; +- mms[i].help = help; +- +- tmpname = &mms_names[i][0]; +- if (ports[i] == MMS_PORT) +- sprintf(tmpname, "mms"); +- else +- sprintf(tmpname, "mms-%d", ports[i]); +- mms[i].name = tmpname; +- +- DEBUGP("ip_conntrack_mms: registering helper for port %d\n", +- ports[i]); +- ret = ip_conntrack_helper_register(&mms[i]); +- +- if (ret) { +- fini(); +- return ret; +- } +- ports_c++; +- } +- return 0; +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_pptp.c +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_pptp.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,531 +0,0 @@ +-/* +- * ip_conntrack_pptp.c - Version 1.11 +- * +- * Connection tracking support for PPTP (Point to Point Tunneling Protocol). +- * PPTP is a a protocol for creating virtual private networks. +- * It is a specification defined by Microsoft and some vendors +- * working with Microsoft. PPTP is built on top of a modified +- * version of the Internet Generic Routing Encapsulation Protocol. +- * GRE is defined in RFC 1701 and RFC 1702. Documentation of +- * PPTP can be found in RFC 2637 +- * +- * (C) 2000-2002 by Harald Welte , +- * +- * Development of this code funded by Astaro AG (http://www.astaro.com/) +- * +- * Limitations: +- * - We blindly assume that control connections are always +- * established in PNS->PAC direction. This is a violation +- * of RFFC2673 +- * +- * TODO: - finish support for multiple calls within one session +- * (needs expect reservations in newnat) +- * - testing of incoming PPTP calls +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Harald Welte "); +-MODULE_DESCRIPTION("Netfilter connection tracking helper module for PPTP"); +- +-DECLARE_LOCK(ip_pptp_lock); +- +-#define DEBUGP(format, args...) +- +-#define SECS *HZ +-#define MINS * 60 SECS +-#define HOURS * 60 MINS +-#define DAYS * 24 HOURS +- +-#define PPTP_GRE_TIMEOUT (10 MINS) +-#define PPTP_GRE_STREAM_TIMEOUT (5 DAYS) +- +-static int pptp_expectfn(struct ip_conntrack *ct) +-{ +- struct ip_conntrack_expect *exp, *other_exp; +- struct ip_conntrack *master; +- +- DEBUGP("increasing timeouts\n"); +- /* increase timeout of GRE data channel conntrack entry */ +- ct->proto.gre.timeout = PPTP_GRE_TIMEOUT; +- ct->proto.gre.stream_timeout = PPTP_GRE_STREAM_TIMEOUT; +- +- master = master_ct(ct); +- if (!master) { +- DEBUGP(" no master!!!\n"); +- return 0; +- } +- +- DEBUGP("completing tuples with ct info\n"); +- /* we can do this, since we're unconfirmed */ +- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key == +- htonl(master->help.ct_pptp_info.pac_call_id)) { +- /* assume PNS->PAC */ +- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = +- htonl(master->help.ct_pptp_info.pns_call_id); +- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = +- htonl(master->help.ct_pptp_info.pns_call_id); +- } else { +- /* assume PAC->PNS */ +- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = +- htonl(master->help.ct_pptp_info.pac_call_id); +- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = +- htonl(master->help.ct_pptp_info.pns_call_id); +- } +- +- return 0; +-} +- +-/* timeout GRE data connections */ +-static int pptp_timeout_related(struct ip_conntrack *ct) +-{ +- struct list_head *cur_item; +- struct ip_conntrack_expect *exp; +- +- list_for_each(cur_item, &ct->sibling_list) { +- exp = list_entry(cur_item, struct ip_conntrack_expect, +- expected_list); +- +- if (!exp->sibling) +- continue; +- +- DEBUGP("setting timeout of conntrack %p to 0\n", +- exp->sibling); +- exp->sibling->proto.gre.timeout = 0; +- exp->sibling->proto.gre.stream_timeout = 0; +- ip_ct_refresh(exp->sibling, 0); +- } +- +- return 0; +-} +- +-/* expect GRE connection in PNS->PAC direction */ +-static inline int +-exp_gre(struct ip_conntrack *master, +- u_int32_t seq, +- u_int16_t callid, +- u_int16_t peer_callid) +-{ +- struct ip_conntrack_expect exp; +- struct ip_conntrack_tuple inv_tuple; +- +- memset(&exp, 0, sizeof(exp)); +- /* tuple in original direction, PAC->PNS */ +- exp.tuple.src.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; +- exp.tuple.src.u.gre.key = htonl(ntohs(peer_callid)); +- exp.tuple.dst.ip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; +- exp.tuple.dst.u.gre.key = htonl(ntohs(callid)); +- exp.tuple.dst.u.gre.protocol = __constant_htons(GRE_PROTOCOL_PPTP); +- exp.tuple.dst.u.gre.version = GRE_VERSION_PPTP; +- exp.tuple.dst.protonum = IPPROTO_GRE; +- +- exp.mask.src.ip = 0xffffffff; +- exp.mask.src.u.all = 0; +- exp.mask.dst.u.all = 0; +- exp.mask.dst.u.gre.key = 0xffffffff; +- exp.mask.dst.u.gre.version = 0xff; +- exp.mask.dst.u.gre.protocol = 0xffff; +- exp.mask.dst.ip = 0xffffffff; +- exp.mask.dst.protonum = 0xffff; +- +- exp.seq = seq; +- exp.expectfn = pptp_expectfn; +- +- exp.help.exp_pptp_info.pac_call_id = ntohs(callid); +- exp.help.exp_pptp_info.pns_call_id = ntohs(peer_callid); +- +- DEBUGP("calling expect_related "); +- DUMP_TUPLE_RAW(&exp.tuple); +- +- /* Add GRE keymap entries */ +- ip_ct_gre_keymap_add(&exp, &exp.tuple, 0); +- invert_tuplepr(&inv_tuple, &exp.tuple); +- ip_ct_gre_keymap_add(&exp, &inv_tuple, 1); +- +- ip_conntrack_expect_related(master, &exp); +- +- return 0; +-} +- +-static inline int +-pptp_inbound_pkt(struct tcphdr *tcph, +- struct pptp_pkt_hdr *pptph, +- size_t datalen, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- struct PptpControlHeader *ctlh; +- union pptp_ctrl_union pptpReq; +- +- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; +- u_int16_t msg, *cid, *pcid; +- u_int32_t seq; +- +- ctlh = (struct PptpControlHeader *) +- ((char *) pptph + sizeof(struct pptp_pkt_hdr)); +- pptpReq.rawreq = (void *) +- ((char *) ctlh + sizeof(struct PptpControlHeader)); +- +- msg = ntohs(ctlh->messageType); +- DEBUGP("inbound control message %s\n", strMName[msg]); +- +- switch (msg) { +- case PPTP_START_SESSION_REPLY: +- /* server confirms new control session */ +- if (info->sstate < PPTP_SESSION_REQUESTED) { +- DEBUGP("%s without START_SESS_REQUEST\n", +- strMName[msg]); +- break; +- } +- if (pptpReq.srep->resultCode == PPTP_START_OK) +- info->sstate = PPTP_SESSION_CONFIRMED; +- else +- info->sstate = PPTP_SESSION_ERROR; +- break; +- +- case PPTP_STOP_SESSION_REPLY: +- /* server confirms end of control session */ +- if (info->sstate > PPTP_SESSION_STOPREQ) { +- DEBUGP("%s without STOP_SESS_REQUEST\n", +- strMName[msg]); +- break; +- } +- if (pptpReq.strep->resultCode == PPTP_STOP_OK) +- info->sstate = PPTP_SESSION_NONE; +- else +- info->sstate = PPTP_SESSION_ERROR; +- break; +- +- case PPTP_OUT_CALL_REPLY: +- /* server accepted call, we now expect GRE frames */ +- if (info->sstate != PPTP_SESSION_CONFIRMED) { +- DEBUGP("%s but no session\n", strMName[msg]); +- break; +- } +- if (info->cstate != PPTP_CALL_OUT_REQ && +- info->cstate != PPTP_CALL_OUT_CONF) { +- DEBUGP("%s without OUTCALL_REQ\n", strMName[msg]); +- break; +- } +- if (pptpReq.ocack->resultCode != PPTP_OUTCALL_CONNECT) { +- info->cstate = PPTP_CALL_NONE; +- break; +- } +- +- cid = &pptpReq.ocack->callID; +- pcid = &pptpReq.ocack->peersCallID; +- +- info->pac_call_id = ntohs(*cid); +- +- if (htons(info->pns_call_id) != *pcid) { +- DEBUGP("%s for unknown callid %u\n", +- strMName[msg], ntohs(*pcid)); +- break; +- } +- +- DEBUGP("%s, CID=%X, PCID=%X\n", strMName[msg], +- ntohs(*cid), ntohs(*pcid)); +- +- info->cstate = PPTP_CALL_OUT_CONF; +- +- seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph); +- exp_gre(ct, seq, *cid, *pcid); +- break; +- +- case PPTP_IN_CALL_REQUEST: +- /* server tells us about incoming call request */ +- if (info->sstate != PPTP_SESSION_CONFIRMED) { +- DEBUGP("%s but no session\n", strMName[msg]); +- break; +- } +- pcid = &pptpReq.icack->peersCallID; +- DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid)); +- info->cstate = PPTP_CALL_IN_REQ; +- info->pac_call_id= ntohs(*pcid); +- break; +- +- case PPTP_IN_CALL_CONNECT: +- /* server tells us about incoming call established */ +- if (info->sstate != PPTP_SESSION_CONFIRMED) { +- DEBUGP("%s but no session\n", strMName[msg]); +- break; +- } +- if (info->sstate != PPTP_CALL_IN_REP +- && info->sstate != PPTP_CALL_IN_CONF) { +- DEBUGP("%s but never sent IN_CALL_REPLY\n", +- strMName[msg]); +- break; +- } +- +- pcid = &pptpReq.iccon->peersCallID; +- cid = &info->pac_call_id; +- +- if (info->pns_call_id != ntohs(*pcid)) { +- DEBUGP("%s for unknown CallID %u\n", +- strMName[msg], ntohs(*cid)); +- break; +- } +- +- DEBUGP("%s, PCID=%X\n", strMName[msg], ntohs(*pcid)); +- info->cstate = PPTP_CALL_IN_CONF; +- +- /* we expect a GRE connection from PAC to PNS */ +- seq = ntohl(tcph->seq) + ((void *)pcid - (void *)pptph); +- exp_gre(ct, seq, *cid, *pcid); +- +- break; +- +- case PPTP_CALL_DISCONNECT_NOTIFY: +- /* server confirms disconnect */ +- cid = &pptpReq.disc->callID; +- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid)); +- info->cstate = PPTP_CALL_NONE; +- +- /* untrack this call id, unexpect GRE packets */ +- pptp_timeout_related(ct); +- /* NEWNAT: look up exp for call id and unexpct_related */ +- break; +- +- case PPTP_WAN_ERROR_NOTIFY: +- break; +- +- case PPTP_ECHO_REQUEST: +- case PPTP_ECHO_REPLY: +- /* I don't have to explain these ;) */ +- break; +- default: +- DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX) +- ? strMName[msg]:strMName[0], msg); +- break; +- } +- +- return NF_ACCEPT; +- +-} +- +-static inline int +-pptp_outbound_pkt(struct tcphdr *tcph, +- struct pptp_pkt_hdr *pptph, +- size_t datalen, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- struct PptpControlHeader *ctlh; +- union pptp_ctrl_union pptpReq; +- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; +- u_int16_t msg, *cid, *pcid; +- +- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph)); +- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh)); +- +- msg = ntohs(ctlh->messageType); +- DEBUGP("outbound control message %s\n", strMName[msg]); +- +- switch (msg) { +- case PPTP_START_SESSION_REQUEST: +- /* client requests for new control session */ +- if (info->sstate != PPTP_SESSION_NONE) { +- DEBUGP("%s but we already have one", +- strMName[msg]); +- } +- info->sstate = PPTP_SESSION_REQUESTED; +- break; +- case PPTP_STOP_SESSION_REQUEST: +- /* client requests end of control session */ +- info->sstate = PPTP_SESSION_STOPREQ; +- break; +- +- case PPTP_OUT_CALL_REQUEST: +- /* client initiating connection to server */ +- if (info->sstate != PPTP_SESSION_CONFIRMED) { +- DEBUGP("%s but no session\n", +- strMName[msg]); +- break; +- } +- info->cstate = PPTP_CALL_OUT_REQ; +- /* track PNS call id */ +- cid = &pptpReq.ocreq->callID; +- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*cid)); +- info->pns_call_id = ntohs(*cid); +- break; +- case PPTP_IN_CALL_REPLY: +- /* client answers incoming call */ +- if (info->cstate != PPTP_CALL_IN_REQ +- && info->cstate != PPTP_CALL_IN_REP) { +- DEBUGP("%s without incall_req\n", +- strMName[msg]); +- break; +- } +- if (pptpReq.icack->resultCode != PPTP_INCALL_ACCEPT) { +- info->cstate = PPTP_CALL_NONE; +- break; +- } +- pcid = &pptpReq.icack->peersCallID; +- if (info->pac_call_id != ntohs(*pcid)) { +- DEBUGP("%s for unknown call %u\n", +- strMName[msg], ntohs(*pcid)); +- break; +- } +- DEBUGP("%s, CID=%X\n", strMName[msg], ntohs(*pcid)); +- /* part two of the three-way handshake */ +- info->cstate = PPTP_CALL_IN_REP; +- info->pns_call_id = ntohs(pptpReq.icack->callID); +- break; +- +- case PPTP_CALL_CLEAR_REQUEST: +- /* client requests hangup of call */ +- if (info->sstate != PPTP_SESSION_CONFIRMED) { +- DEBUGP("CLEAR_CALL but no session\n"); +- break; +- } +- /* FUTURE: iterate over all calls and check if +- * call ID is valid. We don't do this without newnat, +- * because we only know about last call */ +- info->cstate = PPTP_CALL_CLEAR_REQ; +- break; +- case PPTP_SET_LINK_INFO: +- break; +- case PPTP_ECHO_REQUEST: +- case PPTP_ECHO_REPLY: +- /* I don't have to explain these ;) */ +- break; +- default: +- DEBUGP("invalid %s (TY=%d)\n", (msg <= PPTP_MSG_MAX)? +- strMName[msg]:strMName[0], msg); +- /* unknown: no need to create GRE masq table entry */ +- break; +- } +- +- return NF_ACCEPT; +-} +- +- +-/* track caller id inside control connection, call expect_related */ +-static int +-conntrack_pptp_help(const struct iphdr *iph, size_t len, +- struct ip_conntrack *ct, enum ip_conntrack_info ctinfo) +- +-{ +- struct pptp_pkt_hdr *pptph; +- +- struct tcphdr *tcph = (void *) iph + iph->ihl * 4; +- u_int32_t tcplen = len - iph->ihl * 4; +- u_int32_t datalen = tcplen - tcph->doff * 4; +- void *datalimit; +- int dir = CTINFO2DIR(ctinfo); +- struct ip_ct_pptp_master *info = &ct->help.ct_pptp_info; +- +- int oldsstate, oldcstate; +- int ret; +- +- /* don't do any tracking before tcp handshake complete */ +- if (ctinfo != IP_CT_ESTABLISHED +- && ctinfo != IP_CT_ESTABLISHED+IP_CT_IS_REPLY) { +- DEBUGP("ctinfo = %u, skipping\n", ctinfo); +- return NF_ACCEPT; +- } +- +- /* not a complete TCP header? */ +- if (tcplen < sizeof(struct tcphdr) || tcplen < tcph->doff * 4) { +- DEBUGP("tcplen = %u\n", tcplen); +- return NF_ACCEPT; +- } +- +- /* checksum invalid? */ +- if (tcp_v4_check(tcph, tcplen, iph->saddr, iph->daddr, +- csum_partial((char *) tcph, tcplen, 0))) { +- printk(KERN_NOTICE __FILE__ ": bad csum\n"); +-// return NF_ACCEPT; +- } +- +- if (tcph->fin || tcph->rst) { +- DEBUGP("RST/FIN received, timeouting GRE\n"); +- /* can't do this after real newnat */ +- info->cstate = PPTP_CALL_NONE; +- +- /* untrack this call id, unexpect GRE packets */ +- pptp_timeout_related(ct); +- /* no need to call unexpect_related since master conn +- * dies anyway */ +- } +- +- +- pptph = (struct pptp_pkt_hdr *) ((void *) tcph + tcph->doff * 4); +- datalimit = (void *) pptph + datalen; +- +- /* not a full pptp packet header? */ +- if ((void *) pptph+sizeof(*pptph) >= datalimit) { +- DEBUGP("no full PPTP header, can't track\n"); +- return NF_ACCEPT; +- } +- +- /* if it's not a control message we can't do anything with it */ +- if (ntohs(pptph->packetType) != PPTP_PACKET_CONTROL || +- ntohl(pptph->magicCookie) != PPTP_MAGIC_COOKIE) { +- DEBUGP("not a control packet\n"); +- return NF_ACCEPT; +- } +- +- oldsstate = info->sstate; +- oldcstate = info->cstate; +- +- LOCK_BH(&ip_pptp_lock); +- +- if (dir == IP_CT_DIR_ORIGINAL) +- /* client -> server (PNS -> PAC) */ +- ret = pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo); +- else +- /* server -> client (PAC -> PNS) */ +- ret = pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo); +- DEBUGP("sstate: %d->%d, cstate: %d->%d\n", +- oldsstate, info->sstate, oldcstate, info->cstate); +- UNLOCK_BH(&ip_pptp_lock); +- +- return ret; +-} +- +-/* control protocol helper */ +-static struct ip_conntrack_helper pptp = { +- { NULL, NULL }, +- "pptp", IP_CT_HELPER_F_REUSE_EXPECT, THIS_MODULE, 2, 0, +- { { 0, { tcp: { port: __constant_htons(PPTP_CONTROL_PORT) } } }, +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { tcp: { port: 0xffff } } }, +- { 0, { 0 }, 0xffff } }, +- conntrack_pptp_help }; +- +-/* ip_conntrack_pptp initialization */ +-static int __init init(void) +-{ +- int retcode; +- +- DEBUGP(__FILE__ ": registering helper\n"); +- if ((retcode = ip_conntrack_helper_register(&pptp))) { +- printk(KERN_ERR "Unable to register conntrack application " +- "helper for pptp: %d\n", retcode); +- return -EIO; +- } +- +- return 0; +-} +- +-static void __exit fini(void) +-{ +- ip_conntrack_helper_unregister(&pptp); +-} +- +-module_init(init); +-module_exit(fini); +- +-EXPORT_SYMBOL(ip_pptp_lock); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp_priv.h src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_pptp_priv.h +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_pptp_priv.h 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_pptp_priv.h 1969-12-31 19:00:00.000000000 -0500 +@@ -1,24 +0,0 @@ +-#ifndef _IP_CT_PPTP_PRIV_H +-#define _IP_CT_PPTP_PRIV_H +- +-/* PptpControlMessageType names */ +-static const char *strMName[] = { +- "UNKNOWN_MESSAGE", +- "START_SESSION_REQUEST", +- "START_SESSION_REPLY", +- "STOP_SESSION_REQUEST", +- "STOP_SESSION_REPLY", +- "ECHO_REQUEST", +- "ECHO_REPLY", +- "OUT_CALL_REQUEST", +- "OUT_CALL_REPLY", +- "IN_CALL_REQUEST", +- "IN_CALL_REPLY", +- "IN_CALL_CONNECT", +- "CALL_CLEAR_REQUEST", +- "CALL_DISCONNECT_NOTIFY", +- "WAN_ERROR_NOTIFY", +- "SET_LINK_INFO" +-}; +- +-#endif +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_gre.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_gre.c +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_gre.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_gre.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,320 +0,0 @@ +-/* +- * ip_conntrack_proto_gre.c - Version 1.11 +- * +- * Connection tracking protocol helper module for GRE. +- * +- * GRE is a generic encapsulation protocol, which is generally not very +- * suited for NAT, as it has no protocol-specific part as port numbers. +- * +- * It has an optional key field, which may help us distinguishing two +- * connections between the same two hosts. +- * +- * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 +- * +- * PPTP is built on top of a modified version of GRE, and has a mandatory +- * field called "CallID", which serves us for the same purpose as the key +- * field in plain GRE. +- * +- * Documentation about PPTP can be found in RFC 2637 +- * +- * (C) 2000-2002 by Harald Welte +- * +- * Development of this code funded by Astaro AG (http://www.astaro.com/) +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#include +- +-DECLARE_RWLOCK(ip_ct_gre_lock); +-#define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_ct_gre_lock) +-#define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_ct_gre_lock) +- +-#include +-#include +-#include +-#include +- +-#include +-#include +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Harald Welte "); +-MODULE_DESCRIPTION("netfilter connection tracking protocol helper for GRE"); +- +-/* shamelessly stolen from ip_conntrack_proto_udp.c */ +-#define GRE_TIMEOUT (30*HZ) +-#define GRE_STREAM_TIMEOUT (180*HZ) +- +-#define DEBUGP(x, args...) +-#define DUMP_TUPLE_GRE(x) +- +-/* GRE KEYMAP HANDLING FUNCTIONS */ +-static LIST_HEAD(gre_keymap_list); +- +-static inline int gre_key_cmpfn(const struct ip_ct_gre_keymap *km, +- const struct ip_conntrack_tuple *t) +-{ +- return ((km->tuple.src.ip == t->src.ip) && +- (km->tuple.dst.ip == t->dst.ip) && +- (km->tuple.dst.protonum == t->dst.protonum) && +- (km->tuple.dst.u.all == t->dst.u.all)); +-} +- +-/* look up the source key for a given tuple */ +-static u_int32_t gre_keymap_lookup(struct ip_conntrack_tuple *t) +-{ +- struct ip_ct_gre_keymap *km; +- u_int32_t key; +- +- READ_LOCK(&ip_ct_gre_lock); +- km = LIST_FIND(&gre_keymap_list, gre_key_cmpfn, +- struct ip_ct_gre_keymap *, t); +- if (!km) { +- READ_UNLOCK(&ip_ct_gre_lock); +- return 0; +- } +- +- key = km->tuple.src.u.gre.key; +- READ_UNLOCK(&ip_ct_gre_lock); +- +- return key; +-} +- +-/* add a single keymap entry, associate with specified expect */ +-int ip_ct_gre_keymap_add(struct ip_conntrack_expect *exp, +- struct ip_conntrack_tuple *t, int reply) +-{ +- struct ip_ct_gre_keymap *km; +- +- km = kmalloc(sizeof(*km), GFP_ATOMIC); +- if (!km) +- return -1; +- +- /* initializing list head should be sufficient */ +- memset(km, 0, sizeof(*km)); +- +- memcpy(&km->tuple, t, sizeof(*t)); +- km->master = exp; +- +- if (!reply) +- exp->proto.gre.keymap_orig = km; +- else +- exp->proto.gre.keymap_reply = km; +- +- DEBUGP("adding new entry %p: ", km); +- DUMP_TUPLE_GRE(&km->tuple); +- +- WRITE_LOCK(&ip_ct_gre_lock); +- list_append(&gre_keymap_list, km); +- WRITE_UNLOCK(&ip_ct_gre_lock); +- +- return 0; +-} +- +-/* change the tuple of a keymap entry (used by nat helper) */ +-void ip_ct_gre_keymap_change(struct ip_ct_gre_keymap *km, +- struct ip_conntrack_tuple *t) +-{ +- DEBUGP("changing entry %p to: ", km); +- DUMP_TUPLE_GRE(t); +- +- WRITE_LOCK(&ip_ct_gre_lock); +- memcpy(&km->tuple, t, sizeof(km->tuple)); +- WRITE_UNLOCK(&ip_ct_gre_lock); +-} +- +- +-/* PUBLIC CONNTRACK PROTO HELPER FUNCTIONS */ +- +-/* invert gre part of tuple */ +-static int gre_invert_tuple(struct ip_conntrack_tuple *tuple, +- const struct ip_conntrack_tuple *orig) +-{ +- tuple->dst.u.gre.protocol = orig->dst.u.gre.protocol; +- tuple->dst.u.gre.version = orig->dst.u.gre.version; +- +- tuple->dst.u.gre.key = orig->src.u.gre.key; +- tuple->src.u.gre.key = orig->dst.u.gre.key; +- +- return 1; +-} +- +-/* gre hdr info to tuple */ +-static int gre_pkt_to_tuple(const void *datah, size_t datalen, +- struct ip_conntrack_tuple *tuple) +-{ +- struct gre_hdr *grehdr = (struct gre_hdr *) datah; +- struct gre_hdr_pptp *pgrehdr = (struct gre_hdr_pptp *) datah; +- u_int32_t srckey; +- +- /* core guarantees 8 protocol bytes, no need for size check */ +- +- tuple->dst.u.gre.version = grehdr->version; +- tuple->dst.u.gre.protocol = grehdr->protocol; +- +- switch (grehdr->version) { +- case GRE_VERSION_1701: +- if (!grehdr->key) { +- DEBUGP("Can't track GRE without key\n"); +- return 0; +- } +- tuple->dst.u.gre.key = *(gre_key(grehdr)); +- break; +- +- case GRE_VERSION_PPTP: +- if (ntohs(grehdr->protocol) != GRE_PROTOCOL_PPTP) { +- DEBUGP("GRE_VERSION_PPTP but unknown proto\n"); +- return 0; +- } +- tuple->dst.u.gre.key = htonl(ntohs(pgrehdr->call_id)); +- break; +- +- default: +- printk(KERN_WARNING "unknown GRE version %hu\n", +- tuple->dst.u.gre.version); +- return 0; +- } +- +- srckey = gre_keymap_lookup(tuple); +- +- tuple->src.u.gre.key = srckey; +- +- return 1; +-} +- +-/* print gre part of tuple */ +-static unsigned int gre_print_tuple(char *buffer, +- const struct ip_conntrack_tuple *tuple) +-{ +- return sprintf(buffer, "version=%d protocol=0x%04x srckey=0x%x dstkey=0x%x ", +- tuple->dst.u.gre.version, +- ntohs(tuple->dst.u.gre.protocol), +- ntohl(tuple->src.u.gre.key), +- ntohl(tuple->dst.u.gre.key)); +-} +- +-/* print private data for conntrack */ +-static unsigned int gre_print_conntrack(char *buffer, +- const struct ip_conntrack *ct) +-{ +- return sprintf(buffer, "timeout=%u, stream_timeout=%u ", +- (ct->proto.gre.timeout / HZ), +- (ct->proto.gre.stream_timeout / HZ)); +-} +- +-/* Returns verdict for packet, and may modify conntrack */ +-static int gre_packet(struct ip_conntrack *ct, +- struct iphdr *iph, size_t len, +- enum ip_conntrack_info conntrackinfo) +-{ +- /* If we've seen traffic both ways, this is a GRE connection. +- * Extend timeout. */ +- if (ct->status & IPS_SEEN_REPLY) { +- ip_ct_refresh(ct, ct->proto.gre.stream_timeout); +- /* Also, more likely to be important, and not a probe. */ +- set_bit(IPS_ASSURED_BIT, &ct->status); +- } else +- ip_ct_refresh(ct, ct->proto.gre.timeout); +- +- return NF_ACCEPT; +-} +- +-/* Called when a new connection for this protocol found. */ +-static int gre_new(struct ip_conntrack *ct, +- struct iphdr *iph, size_t len) +-{ +- DEBUGP(": "); +- DUMP_TUPLE_GRE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- +- /* initialize to sane value. Ideally a conntrack helper +- * (e.g. in case of pptp) is increasing them */ +- ct->proto.gre.stream_timeout = GRE_STREAM_TIMEOUT; +- ct->proto.gre.timeout = GRE_TIMEOUT; +- +- return 1; +-} +- +-/* Called when a conntrack entry has already been removed from the hashes +- * and is about to be deleted from memory */ +-static void gre_destroy(struct ip_conntrack *ct) +-{ +- struct ip_conntrack_expect *master = ct->master; +- +- DEBUGP(" entering\n"); +- +- if (!master) { +- DEBUGP("no master exp for ct %p\n", ct); +- return; +- } +- +- WRITE_LOCK(&ip_ct_gre_lock); +- if (master->proto.gre.keymap_orig) { +- DEBUGP("removing %p from list\n", master->proto.gre.keymap_orig); +- list_del(&master->proto.gre.keymap_orig->list); +- kfree(master->proto.gre.keymap_orig); +- } +- if (master->proto.gre.keymap_reply) { +- DEBUGP("removing %p from list\n", master->proto.gre.keymap_reply); +- list_del(&master->proto.gre.keymap_reply->list); +- kfree(master->proto.gre.keymap_reply); +- } +- WRITE_UNLOCK(&ip_ct_gre_lock); +-} +- +-/* protocol helper struct */ +-static struct ip_conntrack_protocol gre = { { NULL, NULL }, IPPROTO_GRE, +- "gre", +- gre_pkt_to_tuple, +- gre_invert_tuple, +- gre_print_tuple, +- gre_print_conntrack, +- gre_packet, +- gre_new, +- gre_destroy, +- NULL, +- THIS_MODULE }; +- +-/* ip_conntrack_proto_gre initialization */ +-static int __init init(void) +-{ +- int retcode; +- +- if ((retcode = ip_conntrack_protocol_register(&gre))) { +- printk(KERN_ERR "Unable to register conntrack protocol " +- "helper for gre: %d\n", retcode); +- return -EIO; +- } +- +- return 0; +-} +- +-static void __exit fini(void) +-{ +- struct list_head *pos, *n; +- +- /* delete all keymap entries */ +- WRITE_LOCK(&ip_ct_gre_lock); +- list_for_each_safe(pos, n, &gre_keymap_list) { +- DEBUGP("deleting keymap %p\n", pos); +- list_del(pos); +- kfree(pos); +- } +- WRITE_UNLOCK(&ip_ct_gre_lock); +- +- ip_conntrack_protocol_unregister(&gre); +-} +- +-EXPORT_SYMBOL(ip_ct_gre_keymap_add); +-EXPORT_SYMBOL(ip_ct_gre_keymap_change); +- +-module_init(init); +-module_exit(fini); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2003-08-12 07:33:45.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2004-05-09 04:13:03.000000000 -0400 +@@ -15,11 +15,17 @@ + #include + #include + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + /* Protects conntrack->proto.tcp */ + static DECLARE_RWLOCK(tcp_lock); + ++/* FIXME: Examine ipfilter's timeouts and conntrack transitions more ++ closely. They're more complex. --RR */ + + /* Actually, I believe that neither ipmasq (where this code is stolen + from) nor ipfilter do it exactly right. A new conntrack machine taking +@@ -39,6 +45,25 @@ + "LISTEN" + }; + ++#define SECS *HZ ++#define MINS * 60 SECS ++#define HOURS * 60 MINS ++#define DAYS * 24 HOURS ++ ++ ++static unsigned long tcp_timeouts[] ++= { 30 MINS, /* TCP_CONNTRACK_NONE, */ ++ 5 DAYS, /* TCP_CONNTRACK_ESTABLISHED, */ ++ 2 MINS, /* TCP_CONNTRACK_SYN_SENT, */ ++ 60 SECS, /* TCP_CONNTRACK_SYN_RECV, */ ++ 2 MINS, /* TCP_CONNTRACK_FIN_WAIT, */ ++ 2 MINS, /* TCP_CONNTRACK_TIME_WAIT, */ ++ 10 SECS, /* TCP_CONNTRACK_CLOSE, */ ++ 60 SECS, /* TCP_CONNTRACK_CLOSE_WAIT, */ ++ 30 SECS, /* TCP_CONNTRACK_LAST_ACK, */ ++ 2 MINS, /* TCP_CONNTRACK_LISTEN, */ ++}; ++ + #define sNO TCP_CONNTRACK_NONE + #define sES TCP_CONNTRACK_ESTABLISHED + #define sSS TCP_CONNTRACK_SYN_SENT +@@ -161,13 +186,13 @@ + && tcph->syn && tcph->ack) + conntrack->proto.tcp.handshake_ack + = htonl(ntohl(tcph->seq) + 1); ++ WRITE_UNLOCK(&tcp_lock); + + /* If only reply is a RST, we can consider ourselves not to + have an established connection: this is a fairly common + problem case, so we can delete the conntrack + immediately. --RR */ + if (!(conntrack->status & IPS_SEEN_REPLY) && tcph->rst) { +- WRITE_UNLOCK(&tcp_lock); + if (del_timer(&conntrack->timeout)) + conntrack->timeout.function((unsigned long)conntrack); + } else { +@@ -178,9 +203,7 @@ + && tcph->ack_seq == conntrack->proto.tcp.handshake_ack) + set_bit(IPS_ASSURED_BIT, &conntrack->status); + +- WRITE_UNLOCK(&tcp_lock); +- ip_ct_refresh(conntrack, +- sysctl_ip_conntrack_tcp_timeouts[newconntrack]); ++ ip_ct_refresh(conntrack, tcp_timeouts[newconntrack]); + } + + return NF_ACCEPT; +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_udp.c +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2003-08-12 07:33:45.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2004-05-09 04:13:03.000000000 -0400 +@@ -5,7 +5,9 @@ + #include + #include + #include +-#include ++ ++#define UDP_TIMEOUT (30*HZ) ++#define UDP_STREAM_TIMEOUT (180*HZ) + + static int udp_pkt_to_tuple(const void *datah, size_t datalen, + struct ip_conntrack_tuple *tuple) +@@ -50,13 +52,11 @@ + /* If we've seen traffic both ways, this is some kind of UDP + stream. Extend timeout. */ + if (conntrack->status & IPS_SEEN_REPLY) { +- ip_ct_refresh(conntrack, +- sysctl_ip_conntrack_udp_timeouts[UDP_STREAM_TIMEOUT]); ++ ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT); + /* Also, more likely to be important, and not a probe */ + set_bit(IPS_ASSURED_BIT, &conntrack->status); + } else +- ip_ct_refresh(conntrack, +- sysctl_ip_conntrack_udp_timeouts[UDP_TIMEOUT]); ++ ip_ct_refresh(conntrack, UDP_TIMEOUT); + + return NF_ACCEPT; + } +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_standalone.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_standalone.c +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_standalone.c 2003-08-12 07:33:45.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_standalone.c 2004-05-09 04:13:03.000000000 -0400 +@@ -27,7 +27,11 @@ + #include + #include + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + struct module *ip_conntrack_module = THIS_MODULE; + MODULE_LICENSE("GPL"); +@@ -52,17 +56,12 @@ + return len; + } + ++/* FIXME: Don't print source proto part. --RR */ + static unsigned int + print_expect(char *buffer, const struct ip_conntrack_expect *expect) + { + unsigned int len; + +- if (!expect || !expect->expectant || !expect->expectant->helper) { +- DEBUGP("expect %x expect->expectant %x expect->expectant->helper %x\n", +- expect, expect->expectant, expect->expectant->helper); +- return 0; +- } +- + if (expect->expectant->helper->timeout) + len = sprintf(buffer, "EXPECTING: %lu ", + timer_pending(&expect->timeout) +@@ -294,6 +293,8 @@ + return ret; + } + ++/* FIXME: Allow NULL functions and sub in pointers to generic for ++ them. --RR */ + int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) + { + int ret = 0; +@@ -362,8 +363,6 @@ + EXPORT_SYMBOL(ip_ct_find_proto); + EXPORT_SYMBOL(__ip_ct_find_proto); + EXPORT_SYMBOL(ip_ct_find_helper); +-EXPORT_SYMBOL(sysctl_ip_conntrack_tcp_timeouts); +-EXPORT_SYMBOL(sysctl_ip_conntrack_udp_timeouts); + EXPORT_SYMBOL(ip_conntrack_expect_related); + EXPORT_SYMBOL(ip_conntrack_change_expect); + EXPORT_SYMBOL(ip_conntrack_unexpect_related); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_conntrack_tftp.c src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_tftp.c +--- src/linux/linux/net/ipv4/netfilter/ip_conntrack_tftp.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_conntrack_tftp.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,126 +0,0 @@ +-/* +- * Licensed under GNU GPL version 2 Copyright Magnus Boden +- * Version: 0.0.7 +- * +- * Thu 21 Mar 2002 Harald Welte +- * - port to newnat API +- * +- */ +- +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +- +-MODULE_AUTHOR("Magnus Boden "); +-MODULE_DESCRIPTION("Netfilter connection tracking module for tftp"); +-MODULE_LICENSE("GPL"); +- +-#define MAX_PORTS 8 +-static int ports[MAX_PORTS]; +-static int ports_c = 0; +-#ifdef MODULE_PARM +-MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); +-MODULE_PARM_DESC(ports, "port numbers of tftp servers"); +-#endif +- +-#define DEBUGP(format, args...) +- +-static int tftp_help(const struct iphdr *iph, size_t len, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo) +-{ +- struct udphdr *udph = (void *)iph + iph->ihl * 4; +- struct tftphdr *tftph = (void *)udph + 8; +- struct ip_conntrack_expect exp; +- +- switch (ntohs(tftph->opcode)) { +- /* RRQ and WRQ works the same way */ +- case TFTP_OPCODE_READ: +- case TFTP_OPCODE_WRITE: +- DEBUGP(""); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); +- memset(&exp, 0, sizeof(exp)); +- +- exp.tuple = ct->tuplehash[IP_CT_DIR_REPLY].tuple; +- exp.mask.src.ip = 0xffffffff; +- exp.mask.dst.ip = 0xffffffff; +- exp.mask.dst.u.udp.port = 0xffff; +- exp.mask.dst.protonum = 0xffff; +- exp.expectfn = NULL; +- +- DEBUGP("expect: "); +- DUMP_TUPLE(&exp.tuple); +- DUMP_TUPLE(&exp.mask); +- ip_conntrack_expect_related(ct, &exp); +- break; +- default: +- DEBUGP("Unknown opcode\n"); +- } +- return NF_ACCEPT; +-} +- +-static struct ip_conntrack_helper tftp[MAX_PORTS]; +-static char tftp_names[MAX_PORTS][10]; +- +-static void fini(void) +-{ +- int i; +- +- for (i = 0 ; i < ports_c; i++) { +- DEBUGP("unregistering helper for port %d\n", +- ports[i]); +- ip_conntrack_helper_unregister(&tftp[i]); +- } +-} +- +-static int __init init(void) +-{ +- int i, ret; +- char *tmpname; +- +- if (!ports[0]) +- ports[0]=TFTP_PORT; +- +- for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { +- /* Create helper structure */ +- memset(&tftp[i], 0, sizeof(struct ip_conntrack_helper)); +- +- tftp[i].tuple.dst.protonum = IPPROTO_UDP; +- tftp[i].tuple.src.u.udp.port = htons(ports[i]); +- tftp[i].mask.dst.protonum = 0xFFFF; +- tftp[i].mask.src.u.udp.port = 0xFFFF; +- tftp[i].max_expected = 1; +- tftp[i].timeout = 0; +- tftp[i].flags = IP_CT_HELPER_F_REUSE_EXPECT; +- tftp[i].me = THIS_MODULE; +- tftp[i].help = tftp_help; +- +- tmpname = &tftp_names[i][0]; +- if (ports[i] == TFTP_PORT) +- sprintf(tmpname, "tftp"); +- else +- sprintf(tmpname, "tftp-%d", i); +- tftp[i].name = tmpname; +- +- DEBUGP("port #%d: %d\n", i, ports[i]); +- +- ret=ip_conntrack_helper_register(&tftp[i]); +- if (ret) { +- printk("ERROR registering helper for port %d\n", +- ports[i]); +- fini(); +- return(ret); +- } +- ports_c++; +- } +- return(0); +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_core.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_core.c +--- src/linux/linux/net/ipv4/netfilter/ip_nat_core.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_core.c 2004-05-09 04:13:03.000000000 -0400 +@@ -31,7 +31,11 @@ + #include + #include + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + DECLARE_RWLOCK(ip_nat_lock); + DECLARE_RWLOCK_EXTERN(ip_conntrack_lock); +@@ -207,6 +211,7 @@ + { + struct rtable *rt; + ++ /* FIXME: IPTOS_TOS(iph->tos) --RR */ + if (ip_route_output(&rt, var_ip, 0, 0, 0) != 0) { + DEBUGP("do_extra_mangle: Can't get route to %u.%u.%u.%u\n", + NIPQUAD(var_ip)); +@@ -429,7 +434,7 @@ + *tuple = *orig_tuple; + while ((rptr = find_best_ips_proto_fast(tuple, mr, conntrack, hooknum)) + != NULL) { +- DEBUGP("Found best for "); DUMP_TUPLE_RAW(tuple); ++ DEBUGP("Found best for "); DUMP_TUPLE(tuple); + /* 3) The per-protocol part of the manip is made to + map into the range to make a unique tuple. */ + +@@ -529,6 +534,31 @@ + invert_tuplepr(&orig_tp, + &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple); + ++#if 0 ++ { ++ unsigned int i; ++ ++ DEBUGP("Hook %u (%s), ", hooknum, ++ HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST"); ++ DUMP_TUPLE(&orig_tp); ++ DEBUGP("Range %p: ", mr); ++ for (i = 0; i < mr->rangesize; i++) { ++ DEBUGP("%u:%s%s%s %u.%u.%u.%u - %u.%u.%u.%u %u - %u\n", ++ i, ++ (mr->range[i].flags & IP_NAT_RANGE_MAP_IPS) ++ ? " MAP_IPS" : "", ++ (mr->range[i].flags ++ & IP_NAT_RANGE_PROTO_SPECIFIED) ++ ? " PROTO_SPECIFIED" : "", ++ (mr->range[i].flags & IP_NAT_RANGE_FULL) ++ ? " FULL" : "", ++ NIPQUAD(mr->range[i].min_ip), ++ NIPQUAD(mr->range[i].max_ip), ++ mr->range[i].min.all, ++ mr->range[i].max.all); ++ } ++ } ++#endif + + do { + if (!get_unique_tuple(&new_tuple, &orig_tp, mr, conntrack, +@@ -538,6 +568,15 @@ + return NF_DROP; + } + ++#if 0 ++ DEBUGP("Hook %u (%s) %p\n", hooknum, ++ HOOK2MANIP(hooknum)==IP_NAT_MANIP_SRC ? "SRC" : "DST", ++ conntrack); ++ DEBUGP("Original: "); ++ DUMP_TUPLE(&orig_tp); ++ DEBUGP("New: "); ++ DUMP_TUPLE(&new_tuple); ++#endif + + /* We now have two tuples (SRCIP/SRCPT/DSTIP/DSTPT): + the original (A/B/C/D') and the mangled one (E/F/G/H'). +@@ -554,6 +593,8 @@ + If fail this race (reply tuple now used), repeat. */ + } while (!ip_conntrack_alter_reply(conntrack, &reply)); + ++ /* FIXME: We can simply used existing conntrack reply tuple ++ here --RR */ + /* Create inverse of original: C/D/A/B' */ + invert_tuplepr(&inv_tuple, &orig_tp); + +@@ -678,6 +719,17 @@ + iph->check); + iph->daddr = manip->ip; + } ++#if 0 ++ if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) ++ DEBUGP("IP: checksum on packet bad.\n"); ++ ++ if (proto == IPPROTO_TCP) { ++ void *th = (u_int32_t *)iph + iph->ihl; ++ if (tcp_v4_check(th, len - 4*iph->ihl, iph->saddr, iph->daddr, ++ csum_partial((char *)th, len-4*iph->ihl, 0))) ++ DEBUGP("TCP: checksum on packet bad\n"); ++ } ++#endif + } + + static inline int exp_for_packet(struct ip_conntrack_expect *exp, +@@ -765,6 +817,7 @@ + continue; + + if (exp_for_packet(exp, pskb)) { ++ /* FIXME: May be true multiple times in the case of UDP!! */ + DEBUGP("calling nat helper (exp=%p) for packet\n", + exp); + ret = helper->help(ct, exp, info, ctinfo, +@@ -926,6 +979,7 @@ + INIT_LIST_HEAD(&byipsproto[i]); + } + ++ /* FIXME: Man, this is a hack. */ + IP_NF_ASSERT(ip_conntrack_destroyed == NULL); + ip_conntrack_destroyed = &ip_nat_cleanup_conntrack; + +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_h323.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_h323.c +--- src/linux/linux/net/ipv4/netfilter/ip_nat_h323.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_h323.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,403 +0,0 @@ +-/* +- * H.323 'brute force' extension for NAT alteration. +- * Jozsef Kadlecsik +- * +- * Based on ip_masq_h323.c for 2.2 kernels from CoRiTel, Sofia project. +- * (http://www.coritel.it/projects/sofia/nat.html) +- * Uses Sampsa Ranta's excellent idea on using expectfn to 'bind' +- * the unregistered helpers to the conntrack entries. +- */ +- +- +-#include +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-MODULE_AUTHOR("Jozsef Kadlecsik "); +-MODULE_DESCRIPTION("H.323 'brute force' connection tracking module"); +-MODULE_LICENSE("GPL"); +- +-DECLARE_LOCK_EXTERN(ip_h323_lock); +-struct module *ip_nat_h323 = THIS_MODULE; +- +-#define DEBUGP(format, args...) +- +- +-static unsigned int +-h225_nat_expected(struct sk_buff **pskb, +- unsigned int hooknum, +- struct ip_conntrack *ct, +- struct ip_nat_info *info); +- +-static unsigned int h225_nat_help(struct ip_conntrack *ct, +- struct ip_conntrack_expect *exp, +- struct ip_nat_info *info, +- enum ip_conntrack_info ctinfo, +- unsigned int hooknum, +- struct sk_buff **pskb); +- +-static struct ip_nat_helper h245 = +- { { NULL, NULL }, +- "H.245", /* name */ +- 0, /* flags */ +- NULL, /* module */ +- { { 0, { 0 } }, /* tuple */ +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { 0xFFFF } }, /* mask */ +- { 0, { 0 }, 0xFFFF } }, +- h225_nat_help, /* helper */ +- h225_nat_expected /* expectfn */ +- }; +- +-static unsigned int +-h225_nat_expected(struct sk_buff **pskb, +- unsigned int hooknum, +- struct ip_conntrack *ct, +- struct ip_nat_info *info) +-{ +- struct ip_nat_multi_range mr; +- u_int32_t newdstip, newsrcip, newip; +- u_int16_t port; +- struct ip_ct_h225_expect *exp_info; +- struct ip_ct_h225_master *master_info; +- struct ip_conntrack *master = master_ct(ct); +- unsigned int is_h225, ret; +- +- IP_NF_ASSERT(info); +- IP_NF_ASSERT(master); +- +- IP_NF_ASSERT(!(info->initialized & (1<master->expectant->help.ct_h225_info; +- exp_info = &ct->master->help.exp_h225_info; +- +- LOCK_BH(&ip_h323_lock); +- +- DEBUGP("master: "); +- DUMP_TUPLE(&master->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- DUMP_TUPLE(&master->tuplehash[IP_CT_DIR_REPLY].tuple); +- DEBUGP("conntrack: "); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- if (exp_info->dir == IP_CT_DIR_ORIGINAL) { +- /* Make connection go to the client. */ +- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; +- newsrcip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; +- DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to client)\n", +- NIPQUAD(newsrcip), NIPQUAD(newdstip)); +- } else { +- /* Make the connection go to the server */ +- newdstip = master->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; +- newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- DEBUGP("h225_nat_expected: %u.%u.%u.%u->%u.%u.%u.%u (to server)\n", +- NIPQUAD(newsrcip), NIPQUAD(newdstip)); +- } +- port = exp_info->port; +- is_h225 = master_info->is_h225 == H225_PORT; +- UNLOCK_BH(&ip_h323_lock); +- +- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) +- newip = newsrcip; +- else +- newip = newdstip; +- +- DEBUGP("h225_nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip)); +- +- mr.rangesize = 1; +- /* We don't want to manip the per-protocol, just the IPs... */ +- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; +- mr.range[0].min_ip = mr.range[0].max_ip = newip; +- +- /* ... unless we're doing a MANIP_DST, in which case, make +- sure we map to the correct port */ +- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { +- mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; +- mr.range[0].min = mr.range[0].max +- = ((union ip_conntrack_manip_proto) +- { port }); +- } +- +- ret = ip_nat_setup_info(ct, &mr, hooknum); +- +- if (is_h225) { +- DEBUGP("h225_nat_expected: H.225, setting NAT helper for %p\n", ct); +- /* NAT expectfn called with ip_nat_lock write-locked */ +- info->helper = &h245; +- } +- return ret; +-} +- +-static int h323_signal_address_fixup(struct ip_conntrack *ct, +- struct sk_buff **pskb, +- enum ip_conntrack_info ctinfo) +-{ +- struct iphdr *iph = (*pskb)->nh.iph; +- struct tcphdr *tcph = (void *)iph + iph->ihl*4; +- unsigned char *data; +- u_int32_t tcplen = (*pskb)->len - iph->ihl*4; +- u_int32_t datalen = tcplen - tcph->doff*4; +- struct ip_ct_h225_master *info = &ct->help.ct_h225_info; +- u_int32_t newip; +- u_int16_t port; +- u_int8_t buffer[6]; +- int i; +- +- MUST_BE_LOCKED(&ip_h323_lock); +- +- DEBUGP("h323_signal_address_fixup: %s %s\n", +- between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen) +- ? "yes" : "no", +- between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen) +- ? "yes" : "no"); +- if (!(between(info->seq[IP_CT_DIR_ORIGINAL], ntohl(tcph->seq), ntohl(tcph->seq) + datalen) +- || between(info->seq[IP_CT_DIR_REPLY], ntohl(tcph->seq), ntohl(tcph->seq) + datalen))) +- return 1; +- +- DEBUGP("h323_signal_address_fixup: offsets %u + 6 and %u + 6 in %u\n", +- info->offset[IP_CT_DIR_ORIGINAL], +- info->offset[IP_CT_DIR_REPLY], +- tcplen); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); +- +- for (i = 0; i < IP_CT_DIR_MAX; i++) { +- DEBUGP("h323_signal_address_fixup: %s %s\n", +- info->dir == IP_CT_DIR_ORIGINAL ? "original" : "reply", +- i == IP_CT_DIR_ORIGINAL ? "caller" : "callee"); +- if (!between(info->seq[i], ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen)) +- continue; +- if (!between(info->seq[i] + 6, ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen)) { +- /* Partial retransmisison. It's a cracker being funky. */ +- if (net_ratelimit()) { +- printk("H.323_NAT: partial packet %u/6 in %u/%u\n", +- info->seq[i], +- ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen); +- } +- return 0; +- } +- +- /* Change address inside packet to match way we're mapping +- this connection. */ +- if (i == IP_CT_DIR_ORIGINAL) { +- newip = ct->tuplehash[!info->dir].tuple.dst.ip; +- port = ct->tuplehash[!info->dir].tuple.dst.u.tcp.port; +- } else { +- newip = ct->tuplehash[!info->dir].tuple.src.ip; +- port = ct->tuplehash[!info->dir].tuple.src.u.tcp.port; +- } +- +- data = (char *) tcph + tcph->doff * 4 + info->offset[i]; +- +- DEBUGP("h323_signal_address_fixup: orig %s IP:port %u.%u.%u.%u:%u\n", +- i == IP_CT_DIR_ORIGINAL ? "source" : "dest ", +- data[0], data[1], data[2], data[3], +- (data[4] << 8 | data[5])); +- +- /* Modify the packet */ +- memcpy(buffer, &newip, 4); +- memcpy(buffer + 4, &port, 2); +- if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, info->offset[i], +- 6, buffer, 6)) +- return 0; +- +- DEBUGP("h323_signal_address_fixup: new %s IP:port %u.%u.%u.%u:%u\n", +- i == IP_CT_DIR_ORIGINAL ? "source" : "dest ", +- data[0], data[1], data[2], data[3], +- (data[4] << 8 | data[5])); +- } +- +- return 1; +-} +- +-static int h323_data_fixup(struct ip_ct_h225_expect *info, +- struct ip_conntrack *ct, +- struct sk_buff **pskb, +- enum ip_conntrack_info ctinfo, +- struct ip_conntrack_expect *expect) +-{ +- u_int32_t newip; +- u_int16_t port; +- u_int8_t buffer[6]; +- struct ip_conntrack_tuple newtuple; +- struct iphdr *iph = (*pskb)->nh.iph; +- struct tcphdr *tcph = (void *)iph + iph->ihl*4; +- unsigned char *data; +- u_int32_t tcplen = (*pskb)->len - iph->ihl*4; +- struct ip_ct_h225_master *master_info = &ct->help.ct_h225_info; +- int is_h225; +- +- MUST_BE_LOCKED(&ip_h323_lock); +- DEBUGP("h323_data_fixup: offset %u + 6 in %u\n", info->offset, tcplen); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); +- +- if (!between(expect->seq + 6, ntohl(tcph->seq), +- ntohl(tcph->seq) + tcplen - tcph->doff * 4)) { +- /* Partial retransmisison. It's a cracker being funky. */ +- if (net_ratelimit()) { +- printk("H.323_NAT: partial packet %u/6 in %u/%u\n", +- expect->seq, +- ntohl(tcph->seq), +- ntohl(tcph->seq) + tcplen - tcph->doff * 4); +- } +- return 0; +- } +- +- /* Change address inside packet to match way we're mapping +- this connection. */ +- if (info->dir == IP_CT_DIR_REPLY) { +- /* Must be where client thinks server is */ +- newip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; +- /* Expect something from client->server */ +- newtuple.src.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; +- newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; +- } else { +- /* Must be where server thinks client is */ +- newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- /* Expect something from server->client */ +- newtuple.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; +- newtuple.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- } +- +- is_h225 = (master_info->is_h225 == H225_PORT); +- +- if (is_h225) { +- newtuple.dst.protonum = IPPROTO_TCP; +- newtuple.src.u.tcp.port = expect->tuple.src.u.tcp.port; +- } else { +- newtuple.dst.protonum = IPPROTO_UDP; +- newtuple.src.u.udp.port = expect->tuple.src.u.udp.port; +- } +- +- /* Try to get same port: if not, try to change it. */ +- for (port = ntohs(info->port); port != 0; port++) { +- if (is_h225) +- newtuple.dst.u.tcp.port = htons(port); +- else +- newtuple.dst.u.udp.port = htons(port); +- +- if (ip_conntrack_change_expect(expect, &newtuple) == 0) +- break; +- } +- if (port == 0) { +- DEBUGP("h323_data_fixup: no free port found!\n"); +- return 0; +- } +- +- port = htons(port); +- +- data = (char *) tcph + tcph->doff * 4 + info->offset; +- +- DEBUGP("h323_data_fixup: orig IP:port %u.%u.%u.%u:%u\n", +- data[0], data[1], data[2], data[3], +- (data[4] << 8 | data[5])); +- +- /* Modify the packet */ +- memcpy(buffer, &newip, 4); +- memcpy(buffer + 4, &port, 2); +- if (!ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, info->offset, +- 6, buffer, 6)) +- return 0; +- +- DEBUGP("h323_data_fixup: new IP:port %u.%u.%u.%u:%u\n", +- data[0], data[1], data[2], data[3], +- (data[4] << 8 | data[5])); +- +- return 1; +-} +- +-static unsigned int h225_nat_help(struct ip_conntrack *ct, +- struct ip_conntrack_expect *exp, +- struct ip_nat_info *info, +- enum ip_conntrack_info ctinfo, +- unsigned int hooknum, +- struct sk_buff **pskb) +-{ +- int dir; +- struct ip_ct_h225_expect *exp_info; +- +- /* Only mangle things once: original direction in POST_ROUTING +- and reply direction on PRE_ROUTING. */ +- dir = CTINFO2DIR(ctinfo); +- DEBUGP("nat_h323: dir %s at hook %s\n", +- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); +- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) +- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { +- DEBUGP("nat_h323: Not touching dir %s at hook %s\n", +- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); +- return NF_ACCEPT; +- } +- +- if (!exp) { +- LOCK_BH(&ip_h323_lock); +- if (!h323_signal_address_fixup(ct, pskb, ctinfo)) { +- UNLOCK_BH(&ip_h323_lock); +- return NF_DROP; +- } +- UNLOCK_BH(&ip_h323_lock); +- return NF_ACCEPT; +- } +- +- exp_info = &exp->help.exp_h225_info; +- +- LOCK_BH(&ip_h323_lock); +- if (!h323_data_fixup(exp_info, ct, pskb, ctinfo, exp)) { +- UNLOCK_BH(&ip_h323_lock); +- return NF_DROP; +- } +- UNLOCK_BH(&ip_h323_lock); +- +- return NF_ACCEPT; +-} +- +-static struct ip_nat_helper h225 = +- { { NULL, NULL }, +- "H.225", /* name */ +- IP_NAT_HELPER_F_ALWAYS, /* flags */ +- THIS_MODULE, /* module */ +- { { 0, { __constant_htons(H225_PORT) } }, /* tuple */ +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { 0xFFFF } }, /* mask */ +- { 0, { 0 }, 0xFFFF } }, +- h225_nat_help, /* helper */ +- h225_nat_expected /* expectfn */ +- }; +- +-static int __init init(void) +-{ +- int ret; +- +- ret = ip_nat_helper_register(&h225); +- +- if (ret != 0) +- printk("ip_nat_h323: cannot initialize the module!\n"); +- +- return ret; +-} +- +-static void __exit fini(void) +-{ +- ip_nat_helper_unregister(&h225); +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_helper.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_helper.c +--- src/linux/linux/net/ipv4/netfilter/ip_nat_helper.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_helper.c 2004-05-09 04:13:03.000000000 -0400 +@@ -8,9 +8,6 @@ + * - add support for SACK adjustment + * 14 Mar 2002 Harald Welte : + * - merge SACK support into newnat API +- * 16 Aug 2002 Brian J. Murrell : +- * - make ip_nat_resize_packet more generic (TCP and UDP) +- * - add ip_nat_mangle_udp_packet + */ + #include + #include +@@ -25,7 +22,6 @@ + #include + #include + #include +-#include + + #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_nat_lock) + #define ASSERT_WRITE_LOCK(x) MUST_BE_WRITE_LOCKED(&ip_nat_lock) +@@ -38,8 +34,13 @@ + #include + #include + ++#if 0 ++#define DEBUGP printk ++#define DUMP_OFFSET(x) printk("offset_before=%d, offset_after=%d, correction_pos=%u\n", x->offset_before, x->offset_after, x->correction_pos); ++#else + #define DEBUGP(format, args...) + #define DUMP_OFFSET(x) ++#endif + + DECLARE_LOCK(ip_nat_seqofs_lock); + +@@ -50,12 +51,18 @@ + int new_size) + { + struct iphdr *iph; ++ struct tcphdr *tcph; ++ void *data; + int dir; + struct ip_nat_seq *this_way, *other_way; + + DEBUGP("ip_nat_resize_packet: old_size = %u, new_size = %u\n", + (*skb)->len, new_size); + ++ iph = (*skb)->nh.iph; ++ tcph = (void *)iph + iph->ihl*4; ++ data = (void *)tcph + tcph->doff*4; ++ + dir = CTINFO2DIR(ctinfo); + + this_way = &ct->nat.info.seq[dir]; +@@ -77,9 +84,8 @@ + } + + iph = (*skb)->nh.iph; +- if (iph->protocol == IPPROTO_TCP) { +- struct tcphdr *tcph = (void *)iph + iph->ihl*4; +- void *data = (void *)tcph + tcph->doff*4; ++ tcph = (void *)iph + iph->ihl*4; ++ data = (void *)tcph + tcph->doff*4; + + DEBUGP("ip_nat_resize_packet: Seq_offset before: "); + DUMP_OFFSET(this_way); +@@ -95,20 +101,25 @@ + this_way->correction_pos = ntohl(tcph->seq); + this_way->offset_before = this_way->offset_after; + this_way->offset_after = (int32_t) +- this_way->offset_before + new_size - +- (*skb)->len; ++ this_way->offset_before + new_size - (*skb)->len; + } + + UNLOCK_BH(&ip_nat_seqofs_lock); + + DEBUGP("ip_nat_resize_packet: Seq_offset after: "); + DUMP_OFFSET(this_way); +- } + + return 1; + } + + ++/* Generic function for mangling variable-length address changes inside ++ * NATed connections (like the PORT XXX,XXX,XXX,XXX,XXX,XXX command in FTP). ++ * ++ * Takes care about all the nasty sequence number changes, checksumming, ++ * skb enlargement, ... ++ * ++ * */ + int + ip_nat_mangle_tcp_packet(struct sk_buff **skb, + struct ip_conntrack *ct, +@@ -163,7 +174,6 @@ + tcph = (void *)iph + iph->ihl*4; + data = (void *)tcph + tcph->doff*4; + +- if (rep_len != match_len) + /* move post-replacement */ + memmove(data + match_offset + rep_len, + data + match_offset + match_len, +@@ -198,104 +208,6 @@ + return 1; + } + +-int +-ip_nat_mangle_udp_packet(struct sk_buff **skb, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo, +- unsigned int match_offset, +- unsigned int match_len, +- char *rep_buffer, +- unsigned int rep_len) +-{ +- struct iphdr *iph = (*skb)->nh.iph; +- struct udphdr *udph = (void *)iph + iph->ihl * 4; +- unsigned char *data; +- u_int32_t udplen, newlen, newudplen; +- +- udplen = (*skb)->len - iph->ihl*4; +- newudplen = udplen - match_len + rep_len; +- newlen = iph->ihl*4 + newudplen; +- +- if (newlen > 65535) { +- if (net_ratelimit()) +- printk("ip_nat_mangle_udp_packet: nat'ed packet " +- "exceeds maximum packet size\n"); +- return 0; +- } +- +- if ((*skb)->len != newlen) { +- if (!ip_nat_resize_packet(skb, ct, ctinfo, newlen)) { +- printk("resize_packet failed!!\n"); +- return 0; +- } +- } +- +- /* Alexey says: if a hook changes _data_ ... it can break +- original packet sitting in tcp queue and this is fatal */ +- if (skb_cloned(*skb)) { +- struct sk_buff *nskb = skb_copy(*skb, GFP_ATOMIC); +- if (!nskb) { +- if (net_ratelimit()) +- printk("Out of memory cloning TCP packet\n"); +- return 0; +- } +- /* Rest of kernel will get very unhappy if we pass it +- a suddenly-orphaned skbuff */ +- if ((*skb)->sk) +- skb_set_owner_w(nskb, (*skb)->sk); +- kfree_skb(*skb); +- *skb = nskb; +- } +- +- /* skb may be copied !! */ +- iph = (*skb)->nh.iph; +- udph = (void *)iph + iph->ihl*4; +- data = (void *)udph + sizeof(struct udphdr); +- +- if (rep_len != match_len) +- /* move post-replacement */ +- memmove(data + match_offset + rep_len, +- data + match_offset + match_len, +- (*skb)->tail - (data + match_offset + match_len)); +- +- /* insert data from buffer */ +- memcpy(data + match_offset, rep_buffer, rep_len); +- +- /* update skb info */ +- if (newlen > (*skb)->len) { +- DEBUGP("ip_nat_mangle_udp_packet: Extending packet by " +- "%u to %u bytes\n", newlen - (*skb)->len, newlen); +- skb_put(*skb, newlen - (*skb)->len); +- } else { +- DEBUGP("ip_nat_mangle_udp_packet: Shrinking packet from " +- "%u to %u bytes\n", (*skb)->len, newlen); +- skb_trim(*skb, newlen); +- } +- +- /* update the length of the UDP and IP packets to the new values*/ +- udph->len = htons((*skb)->len - iph->ihl*4); +- iph->tot_len = htons(newlen); +- +- /* fix udp checksum if udp checksum was previously calculated */ +- if ((*skb)->csum != 0) { +- (*skb)->csum = csum_partial((char *)udph + +- sizeof(struct udphdr), +- newudplen - sizeof(struct udphdr), +- 0); +- +- udph->check = 0; +- udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr, +- newudplen, IPPROTO_UDP, +- csum_partial((char *)udph, +- sizeof(struct udphdr), +- (*skb)->csum)); +- } +- +- ip_send_check(iph); +- +- return 1; +-} +- + /* Adjust one found SACK option including checksum correction */ + static void + sack_adjust(struct tcphdr *tcph, +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_mms.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_mms.c +--- src/linux/linux/net/ipv4/netfilter/ip_nat_mms.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_mms.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,330 +0,0 @@ +-/* MMS extension for TCP NAT alteration. +- * (C) 2002 by Filip Sneppe +- * based on ip_nat_ftp.c and ip_nat_irc.c +- * +- * ip_nat_mms.c v0.3 2002-09-22 +- * +- * This program is free software; you can redistribute it and/or +- * modify it under the terms of the GNU General Public License +- * as published by the Free Software Foundation; either version +- * 2 of the License, or (at your option) any later version. +- * +- * Module load syntax: +- * insmod ip_nat_mms.o ports=port1,port2,...port +- * +- * Please give the ports of all MMS servers You wish to connect to. +- * If you don't specify ports, the default will be TCP port 1755. +- * +- * More info on MMS protocol, firewalls and NAT: +- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwmt/html/MMSFirewall.asp +- * http://www.microsoft.com/windows/windowsmedia/serve/firewall.asp +- * +- * The SDP project people are reverse-engineering MMS: +- * http://get.to/sdp +- */ +- +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define DEBUGP(format, args...) +-#define DUMP_BYTES(address, counter) +- +-#define MAX_PORTS 8 +-static int ports[MAX_PORTS]; +-static int ports_c = 0; +- +-#ifdef MODULE_PARM +-MODULE_PARM(ports, "1-" __MODULE_STRING(MAX_PORTS) "i"); +-#endif +- +-MODULE_AUTHOR("Filip Sneppe "); +-MODULE_DESCRIPTION("Microsoft Windows Media Services (MMS) NAT module"); +-MODULE_LICENSE("GPL"); +- +-DECLARE_LOCK_EXTERN(ip_mms_lock); +- +- +-static int mms_data_fixup(const struct ip_ct_mms_expect *ct_mms_info, +- struct ip_conntrack *ct, +- struct sk_buff **pskb, +- enum ip_conntrack_info ctinfo, +- struct ip_conntrack_expect *expect) +-{ +- u_int32_t newip; +- struct ip_conntrack_tuple t; +- struct iphdr *iph = (*pskb)->nh.iph; +- struct tcphdr *tcph = (void *) iph + iph->ihl * 4; +- char *data = (char *)tcph + tcph->doff * 4; +- int i, j, k, port; +- u_int16_t mms_proto; +- +- u_int32_t *mms_chunkLenLV = (u_int32_t *)(data + MMS_SRV_CHUNKLENLV_OFFSET); +- u_int32_t *mms_chunkLenLM = (u_int32_t *)(data + MMS_SRV_CHUNKLENLM_OFFSET); +- u_int32_t *mms_messageLength = (u_int32_t *)(data + MMS_SRV_MESSAGELENGTH_OFFSET); +- +- int zero_padding; +- +- char buffer[28]; /* "\\255.255.255.255\UDP\65635" * 2 (for unicode) */ +- char unicode_buffer[75]; /* 27*2 (unicode) + 20 + 1 */ +- char proto_string[6]; +- +- MUST_BE_LOCKED(&ip_mms_lock); +- +- /* what was the protocol again ? */ +- mms_proto = expect->tuple.dst.protonum; +- sprintf(proto_string, "%u", mms_proto); +- +- DEBUGP("ip_nat_mms: mms_data_fixup: info (seq %u + %u) in %u, proto %s\n", +- expect->seq, ct_mms_info->len, ntohl(tcph->seq), +- mms_proto == IPPROTO_UDP ? "UDP" +- : mms_proto == IPPROTO_TCP ? "TCP":proto_string); +- +- newip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- +- /* Alter conntrack's expectations. */ +- t = expect->tuple; +- t.dst.ip = newip; +- for (port = ct_mms_info->port; port != 0; port++) { +- t.dst.u.tcp.port = htons(port); +- if (ip_conntrack_change_expect(expect, &t) == 0) { +- DEBUGP("ip_nat_mms: mms_data_fixup: using port %d\n", port); +- break; +- } +- } +- +- if(port == 0) +- return 0; +- +- sprintf(buffer, "\\\\%u.%u.%u.%u\\%s\\%u", +- NIPQUAD(newip), +- expect->tuple.dst.protonum == IPPROTO_UDP ? "UDP" +- : expect->tuple.dst.protonum == IPPROTO_TCP ? "TCP":proto_string, +- port); +- DEBUGP("ip_nat_mms: new unicode string=%s\n", buffer); +- +- memset(unicode_buffer, 0, sizeof(char)*75); +- +- for (i=0; ipadding, ct_mms_info->len); +- DEBUGP("ip_nat_mms: mms_data_fixup: offset: %u\n", MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len); +- DUMP_BYTES(data+MMS_SRV_UNICODE_STRING_OFFSET, 60); +- +- /* add end of packet to it */ +- for (j=0; jpadding; ++j) { +- DEBUGP("ip_nat_mms: mms_data_fixup: i=%u j=%u byte=%u\n", +- i, j, (u8)*(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j)); +- *(unicode_buffer+i*2+j) = *(data+MMS_SRV_UNICODE_STRING_OFFSET+ct_mms_info->len+j); +- } +- +- /* pad with zeroes at the end ? see explanation of weird math below */ +- zero_padding = (8-(strlen(buffer)*2 + ct_mms_info->padding + 4)%8)%8; +- for (k=0; k chunkLenLV=%u chunkLenLM=%u messageLength=%u\n", +- *mms_chunkLenLV, *mms_chunkLenLM, *mms_messageLength); +- +- /* explanation, before I forget what I did: +- strlen(buffer)*2 + ct_mms_info->padding + 4 must be divisable by 8; +- divide by 8 and add 3 to compute the mms_chunkLenLM field, +- but note that things may have to be padded with zeroes to align by 8 +- bytes, hence we add 7 and divide by 8 to get the correct length */ +- *mms_chunkLenLM = (u_int32_t) (3+(strlen(buffer)*2+ct_mms_info->padding+11)/8); +- *mms_chunkLenLV = *mms_chunkLenLM+2; +- *mms_messageLength = *mms_chunkLenLV*8; +- +- DEBUGP("ip_nat_mms: modified=> chunkLenLV=%u chunkLenLM=%u messageLength=%u\n", +- *mms_chunkLenLV, *mms_chunkLenLM, *mms_messageLength); +- +- ip_nat_mangle_tcp_packet(pskb, ct, ctinfo, +- expect->seq - ntohl(tcph->seq), +- ct_mms_info->len + ct_mms_info->padding, unicode_buffer, +- strlen(buffer)*2 + ct_mms_info->padding + zero_padding); +- DUMP_BYTES(unicode_buffer, 60); +- +- return 1; +-} +- +-static unsigned int +-mms_nat_expected(struct sk_buff **pskb, +- unsigned int hooknum, +- struct ip_conntrack *ct, +- struct ip_nat_info *info) +-{ +- struct ip_nat_multi_range mr; +- u_int32_t newdstip, newsrcip, newip; +- +- struct ip_conntrack *master = master_ct(ct); +- +- IP_NF_ASSERT(info); +- IP_NF_ASSERT(master); +- +- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); +- +- DEBUGP("ip_nat_mms: mms_nat_expected: We have a connection!\n"); +- +- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; +- newsrcip = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.ip; +- DEBUGP("ip_nat_mms: mms_nat_expected: hook %s: newsrc->newdst %u.%u.%u.%u->%u.%u.%u.%u\n", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???", +- NIPQUAD(newsrcip), NIPQUAD(newdstip)); +- +- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) +- newip = newsrcip; +- else +- newip = newdstip; +- +- DEBUGP("ip_nat_mms: mms_nat_expected: IP to %u.%u.%u.%u\n", NIPQUAD(newip)); +- +- mr.rangesize = 1; +- /* We don't want to manip the per-protocol, just the IPs. */ +- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; +- mr.range[0].min_ip = mr.range[0].max_ip = newip; +- +- return ip_nat_setup_info(ct, &mr, hooknum); +-} +- +- +-static unsigned int mms_nat_help(struct ip_conntrack *ct, +- struct ip_conntrack_expect *exp, +- struct ip_nat_info *info, +- enum ip_conntrack_info ctinfo, +- unsigned int hooknum, +- struct sk_buff **pskb) +-{ +- struct iphdr *iph = (*pskb)->nh.iph; +- struct tcphdr *tcph = (void *) iph + iph->ihl * 4; +- unsigned int datalen; +- int dir; +- struct ip_ct_mms_expect *ct_mms_info; +- +- if (!exp) +- DEBUGP("ip_nat_mms: no exp!!"); +- +- ct_mms_info = &exp->help.exp_mms_info; +- +- /* Only mangle things once: original direction in POST_ROUTING +- and reply direction on PRE_ROUTING. */ +- dir = CTINFO2DIR(ctinfo); +- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) +- ||(hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { +- DEBUGP("ip_nat_mms: mms_nat_help: not touching dir %s at hook %s\n", +- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); +- return NF_ACCEPT; +- } +- DEBUGP("ip_nat_mms: mms_nat_help: beyond not touching (dir %s at hook %s)\n", +- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); +- +- datalen = (*pskb)->len - iph->ihl * 4 - tcph->doff * 4; +- +- DEBUGP("ip_nat_mms: mms_nat_help: %u+%u=%u %u %u\n", exp->seq, ct_mms_info->len, +- exp->seq + ct_mms_info->len, +- ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen); +- +- LOCK_BH(&ip_mms_lock); +- /* Check wether the whole IP/proto/port pattern is carried in the payload */ +- if (between(exp->seq + ct_mms_info->len, +- ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen)) { +- if (!mms_data_fixup(ct_mms_info, ct, pskb, ctinfo, exp)) { +- UNLOCK_BH(&ip_mms_lock); +- return NF_DROP; +- } +- } else { +- /* Half a match? This means a partial retransmisison. +- It's a cracker being funky. */ +- if (net_ratelimit()) { +- printk("ip_nat_mms: partial packet %u/%u in %u/%u\n", +- exp->seq, ct_mms_info->len, +- ntohl(tcph->seq), +- ntohl(tcph->seq) + datalen); +- } +- UNLOCK_BH(&ip_mms_lock); +- return NF_DROP; +- } +- UNLOCK_BH(&ip_mms_lock); +- +- return NF_ACCEPT; +-} +- +-static struct ip_nat_helper mms[MAX_PORTS]; +-static char mms_names[MAX_PORTS][10]; +- +-/* Not __exit: called from init() */ +-static void fini(void) +-{ +- int i; +- +- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { +- DEBUGP("ip_nat_mms: unregistering helper for port %d\n", ports[i]); +- ip_nat_helper_unregister(&mms[i]); +- } +-} +- +-static int __init init(void) +-{ +- int i, ret = 0; +- char *tmpname; +- +- if (ports[0] == 0) +- ports[0] = MMS_PORT; +- +- for (i = 0; (i < MAX_PORTS) && ports[i]; i++) { +- +- memset(&mms[i], 0, sizeof(struct ip_nat_helper)); +- +- mms[i].tuple.dst.protonum = IPPROTO_TCP; +- mms[i].tuple.src.u.tcp.port = htons(ports[i]); +- mms[i].mask.dst.protonum = 0xFFFF; +- mms[i].mask.src.u.tcp.port = 0xFFFF; +- mms[i].help = mms_nat_help; +- mms[i].me = THIS_MODULE; +- mms[i].flags = 0; +- mms[i].expect = mms_nat_expected; +- +- tmpname = &mms_names[i][0]; +- if (ports[i] == MMS_PORT) +- sprintf(tmpname, "mms"); +- else +- sprintf(tmpname, "mms-%d", i); +- mms[i].name = tmpname; +- +- DEBUGP("ip_nat_mms: register helper for port %d\n", +- ports[i]); +- ret = ip_nat_helper_register(&mms[i]); +- +- if (ret) { +- printk("ip_nat_mms: error registering " +- "helper for port %d\n", ports[i]); +- fini(); +- return ret; +- } +- ports_c++; +- } +- +- return ret; +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_pptp.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_pptp.c +--- src/linux/linux/net/ipv4/netfilter/ip_nat_pptp.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_pptp.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,412 +0,0 @@ +-/* +- * ip_nat_pptp.c - Version 1.11 +- * +- * NAT support for PPTP (Point to Point Tunneling Protocol). +- * PPTP is a a protocol for creating virtual private networks. +- * It is a specification defined by Microsoft and some vendors +- * working with Microsoft. PPTP is built on top of a modified +- * version of the Internet Generic Routing Encapsulation Protocol. +- * GRE is defined in RFC 1701 and RFC 1702. Documentation of +- * PPTP can be found in RFC 2637 +- * +- * (C) 2000-2002 by Harald Welte +- * +- * Development of this code funded by Astaro AG (http://www.astaro.com/) +- * +- * TODO: - Support for multiple calls within one session +- * (needs netfilter newnat code) +- * - NAT to a unique tuple, not to TCP source port +- * (needs netfilter tuple reservation) +- * - Support other NAT scenarios than SNAT of PNS +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Harald Welte "); +-MODULE_DESCRIPTION("Netfilter NAT helper module for PPTP"); +- +- +-#define DEBUGP(format, args...) +- +-static unsigned int +-pptp_nat_expected(struct sk_buff **pskb, +- unsigned int hooknum, +- struct ip_conntrack *ct, +- struct ip_nat_info *info) +-{ +- struct ip_conntrack *master = master_ct(ct); +- struct ip_nat_multi_range mr; +- struct ip_ct_pptp_master *ct_pptp_info; +- struct ip_nat_pptp *nat_pptp_info; +- u_int32_t newsrcip, newdstip, newcid; +- int ret; +- +- IP_NF_ASSERT(info); +- IP_NF_ASSERT(master); +- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); +- +- DEBUGP("we have a connection!\n"); +- +- LOCK_BH(&ip_pptp_lock); +- ct_pptp_info = &master->help.ct_pptp_info; +- nat_pptp_info = &master->nat.help.nat_pptp_info; +- +- /* need to alter GRE tuple because conntrack expectfn() used 'wrong' +- * (unmanipulated) values */ +- if (hooknum == NF_IP_PRE_ROUTING) { +- DEBUGP("completing tuples with NAT info \n"); +- /* we can do this, since we're unconfirmed */ +- if (ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.u.gre.key == +- htonl(ct_pptp_info->pac_call_id)) { +- /* assume PNS->PAC */ +- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = +- htonl(nat_pptp_info->pns_call_id); +-// ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u.gre.key = +-// htonl(nat_pptp_info->pac_call_id); +- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = +- htonl(nat_pptp_info->pns_call_id); +- } else { +- /* assume PAC->PNS */ +- DEBUGP("WRONG DIRECTION\n"); +- ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.gre.key = +- htonl(nat_pptp_info->pac_call_id); +- ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u.gre.key = +- htonl(nat_pptp_info->pns_call_id); +- } +- } +- +- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_DST) { +- newdstip = master->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip; +- newcid = htonl(master->nat.help.nat_pptp_info.pac_call_id); +- +- mr.rangesize = 1; +- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS | IP_NAT_RANGE_PROTO_SPECIFIED; +- mr.range[0].min_ip = mr.range[0].max_ip = newdstip; +- mr.range[0].min = mr.range[0].max = +- ((union ip_conntrack_manip_proto ) { newcid }); +- DEBUGP("change dest ip to %u.%u.%u.%u\n", +- NIPQUAD(newdstip)); +- DEBUGP("change dest key to 0x%x\n", ntohl(newcid)); +- ret = ip_nat_setup_info(ct, &mr, hooknum); +- } else { +- newsrcip = master->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- /* nat_multi_range is in network byte order, and GRE tuple +- * is 32 bits, not 16 like callID */ +- newcid = htonl(master->help.ct_pptp_info.pns_call_id); +- +- mr.rangesize = 1; +- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS +- |IP_NAT_RANGE_PROTO_SPECIFIED; +- mr.range[0].min_ip = mr.range[0].max_ip = newsrcip; +- mr.range[0].min = mr.range[0].max = +- ((union ip_conntrack_manip_proto ) { newcid }); +- DEBUGP("change src ip to %u.%u.%u.%u\n", +- NIPQUAD(newsrcip)); +- DEBUGP("change 'src' key to 0x%x\n", ntohl(newcid)); +- ret = ip_nat_setup_info(ct, &mr, hooknum); +- } +- +- UNLOCK_BH(&ip_pptp_lock); +- +- return ret; +- +-} +- +-/* outbound packets == from PNS to PAC */ +-static inline unsigned int +-pptp_outbound_pkt(struct tcphdr *tcph, struct pptp_pkt_hdr *pptph, +- size_t datalen, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo, +- struct ip_conntrack_expect *exp) +- +-{ +- struct PptpControlHeader *ctlh; +- union pptp_ctrl_union pptpReq; +- struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info; +- struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info; +- +- u_int16_t msg, *cid = NULL, new_callid; +- +- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph)); +- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh)); +- +- new_callid = htons(ct_pptp_info->pns_call_id); +- +- switch (msg = ntohs(ctlh->messageType)) { +- case PPTP_OUT_CALL_REQUEST: +- cid = &pptpReq.ocreq->callID; +- +- /* save original call ID in nat_info */ +- nat_pptp_info->pns_call_id = ct_pptp_info->pns_call_id; +- +- new_callid = tcph->source; +- /* save new call ID in ct info */ +- ct_pptp_info->pns_call_id = ntohs(new_callid); +- break; +- case PPTP_IN_CALL_REPLY: +- cid = &pptpReq.icreq->callID; +- break; +- case PPTP_CALL_CLEAR_REQUEST: +- cid = &pptpReq.clrreq->callID; +- break; +- case PPTP_CALL_DISCONNECT_NOTIFY: +- cid = &pptpReq.disc->callID; +- break; +- +- default: +- DEBUGP("unknown outbound packet 0x%04x:%s\n", msg, +- (msg <= PPTP_MSG_MAX)? strMName[msg]:strMName[0]); +- /* fall through */ +- +- case PPTP_SET_LINK_INFO: +- /* only need to NAT in case PAC is behind NAT box */ +- case PPTP_START_SESSION_REQUEST: +- case PPTP_START_SESSION_REPLY: +- case PPTP_STOP_SESSION_REQUEST: +- case PPTP_STOP_SESSION_REPLY: +- case PPTP_ECHO_REQUEST: +- case PPTP_ECHO_REPLY: +- /* no need to alter packet */ +- return NF_ACCEPT; +- } +- +- IP_NF_ASSERT(cid); +- +- DEBUGP("altering call id from 0x%04x to 0x%04x\n", +- ntohs(*cid), ntohs(new_callid)); +- /* mangle packet */ +- tcph->check = ip_nat_cheat_check(*cid^0xFFFF, +- new_callid, tcph->check); +- *cid = new_callid; +- +- return NF_ACCEPT; +-} +- +-/* inbound packets == from PAC to PNS */ +-static inline unsigned int +-pptp_inbound_pkt(struct tcphdr *tcph, struct pptp_pkt_hdr *pptph, +- size_t datalen, +- struct ip_conntrack *ct, +- enum ip_conntrack_info ctinfo, +- struct ip_conntrack_expect *oldexp) +-{ +- struct PptpControlHeader *ctlh; +- union pptp_ctrl_union pptpReq; +- struct ip_ct_pptp_master *ct_pptp_info = &ct->help.ct_pptp_info; +- struct ip_nat_pptp *nat_pptp_info = &ct->nat.help.nat_pptp_info; +- +- u_int16_t msg, new_cid = 0, new_pcid, *pcid = NULL, *cid = NULL; +- u_int32_t old_dst_ip; +- +- struct ip_conntrack_tuple t; +- +- ctlh = (struct PptpControlHeader *) ((void *) pptph + sizeof(*pptph)); +- pptpReq.rawreq = (void *) ((void *) ctlh + sizeof(*ctlh)); +- +- new_pcid = htons(nat_pptp_info->pns_call_id); +- +- switch (msg = ntohs(ctlh->messageType)) { +- case PPTP_OUT_CALL_REPLY: +- pcid = &pptpReq.ocack->peersCallID; +- cid = &pptpReq.ocack->callID; +- if (!oldexp) { +- DEBUGP("outcall but no expectation\n"); +- break; +- } +- old_dst_ip = oldexp->tuple.dst.ip; +- t = oldexp->tuple; +- +- /* save original PAC call ID in nat_info */ +- nat_pptp_info->pac_call_id = ct_pptp_info->pac_call_id; +- +- /* store new callID in ct_info, so conntrack works */ +- //ct_pptp_info->pac_call_id = ntohs(tcph->source); +- //new_cid = htons(ct_pptp_info->pac_call_id); +- +- /* alter expectation */ +- if (t.dst.ip == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip) { +- /* expectation for PNS->PAC direction */ +- t.dst.u.gre.key = htonl(ct_pptp_info->pac_call_id); +- t.src.u.gre.key = htonl(nat_pptp_info->pns_call_id); +- } else { +- /* expectation for PAC->PNS direction */ +- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- DEBUGP("EXPECTATION IN WRONG DIRECTION!!!\n"); +- } +- +- if (!ip_conntrack_change_expect(oldexp, &t)) { +- DEBUGP("successfully changed expect\n"); +- } else { +- DEBUGP("can't change expect\n"); +- } +- ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_orig, &t); +- /* reply keymap */ +- t.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.ip; +- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- t.src.u.gre.key = htonl(nat_pptp_info->pac_call_id); +- t.dst.u.gre.key = htonl(ct_pptp_info->pns_call_id); +- ip_ct_gre_keymap_change(oldexp->proto.gre.keymap_reply, &t); +- +- break; +- case PPTP_IN_CALL_CONNECT: +- pcid = &pptpReq.iccon->peersCallID; +- if (!oldexp) +- break; +- old_dst_ip = oldexp->tuple.dst.ip; +- t = oldexp->tuple; +- +- /* alter expectation, no need for callID */ +- if (t.dst.ip == ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.dst.ip) { +- /* expectation for PNS->PAC direction */ +- t.src.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- } else { +- /* expectation for PAC->PNS direction */ +- t.dst.ip = ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip; +- } +- +- if (!ip_conntrack_change_expect(oldexp, &t)) { +- DEBUGP("successfully changed expect\n"); +- } else { +- DEBUGP("can't change expect\n"); +- } +- break; +- case PPTP_IN_CALL_REQUEST: +- /* only need to nat in case PAC is behind NAT box */ +- break; +- case PPTP_WAN_ERROR_NOTIFY: +- pcid = &pptpReq.wanerr->peersCallID; +- break; +- default: +- DEBUGP("unknown inbound packet %s\n", +- (msg <= PPTP_MSG_MAX)? strMName[msg]:strMName[0]); +- /* fall through */ +- +- case PPTP_START_SESSION_REQUEST: +- case PPTP_START_SESSION_REPLY: +- case PPTP_STOP_SESSION_REQUEST: +- case PPTP_ECHO_REQUEST: +- case PPTP_ECHO_REPLY: +- /* no need to alter packet */ +- return NF_ACCEPT; +- } +- +- /* mangle packet */ +- IP_NF_ASSERT(pcid); +- DEBUGP("altering peer call id from 0x%04x to 0x%04x\n", +- ntohs(*pcid), ntohs(new_pcid)); +- tcph->check = ip_nat_cheat_check(*pcid^0xFFFF, +- new_pcid, tcph->check); +- *pcid = new_pcid; +- +- if (new_cid) { +- IP_NF_ASSERT(cid); +- DEBUGP("altering call id from 0x%04x to 0x%04x\n", +- ntohs(*cid), ntohs(new_cid)); +- tcph->check = ip_nat_cheat_check(*cid^0xFFFF, +- new_cid, tcph->check); +- *cid = new_cid; +- } +- +- /* great, at least we don't need to resize packets */ +- return NF_ACCEPT; +-} +- +- +-static unsigned int tcp_help(struct ip_conntrack *ct, +- struct ip_conntrack_expect *exp, +- struct ip_nat_info *info, +- enum ip_conntrack_info ctinfo, +- unsigned int hooknum, struct sk_buff **pskb) +-{ +- struct iphdr *iph = (*pskb)->nh.iph; +- struct tcphdr *tcph = (void *) iph + iph->ihl*4; +- unsigned int datalen = (*pskb)->len - iph->ihl*4 - tcph->doff*4; +- struct pptp_pkt_hdr *pptph; +- void *datalimit; +- +- int dir; +- +- DEBUGP("entering\n"); +- +- /* Only mangle things once: original direction in POST_ROUTING +- and reply direction on PRE_ROUTING. */ +- dir = CTINFO2DIR(ctinfo); +- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) +- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) { +- DEBUGP("Not touching dir %s at hook %s\n", +- dir == IP_CT_DIR_ORIGINAL ? "ORIG" : "REPLY", +- hooknum == NF_IP_POST_ROUTING ? "POSTROUTING" +- : hooknum == NF_IP_PRE_ROUTING ? "PREROUTING" +- : hooknum == NF_IP_LOCAL_OUT ? "OUTPUT" : "???"); +- return NF_ACCEPT; +- } +- +- /* if packet is too small, just skip it */ +- if (datalen < sizeof(struct pptp_pkt_hdr)+ +- sizeof(struct PptpControlHeader)) { +- DEBUGP("pptp packet too short\n"); +- return NF_ACCEPT; +- } +- +- +- pptph = (struct pptp_pkt_hdr *) ((void *)tcph + tcph->doff*4); +- datalimit = (void *) pptph + datalen; +- +- LOCK_BH(&ip_pptp_lock); +- +- if (dir == IP_CT_DIR_ORIGINAL) { +- /* reuqests sent by client to server (PNS->PAC) */ +- pptp_outbound_pkt(tcph, pptph, datalen, ct, ctinfo, exp); +- } else { +- /* response from the server to the client (PAC->PNS) */ +- pptp_inbound_pkt(tcph, pptph, datalen, ct, ctinfo, exp); +- } +- +- UNLOCK_BH(&ip_pptp_lock); +- +- return NF_ACCEPT; +-} +- +-/* nat helper struct for control connection */ +-static struct ip_nat_helper pptp_tcp_helper = { +- { NULL, NULL }, +- "pptp", IP_NAT_HELPER_F_ALWAYS, THIS_MODULE, +- { { 0, { tcp: { port: __constant_htons(PPTP_CONTROL_PORT) } } }, +- { 0, { 0 }, IPPROTO_TCP } }, +- { { 0, { tcp: { port: 0xFFFF } } }, +- { 0, { 0 }, 0xFFFF } }, +- tcp_help, pptp_nat_expected }; +- +- +-static int __init init(void) +-{ +- DEBUGP("init_module\n" ); +- +- if (ip_nat_helper_register(&pptp_tcp_helper)) +- return -EIO; +- +- return 0; +-} +- +-static void __exit fini(void) +-{ +- DEBUGP("cleanup_module\n" ); +- ip_nat_helper_unregister(&pptp_tcp_helper); +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_proto_gre.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_proto_gre.c +--- src/linux/linux/net/ipv4/netfilter/ip_nat_proto_gre.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_proto_gre.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,212 +0,0 @@ +-/* +- * ip_nat_proto_gre.c - Version 1.11 +- * +- * NAT protocol helper module for GRE. +- * +- * GRE is a generic encapsulation protocol, which is generally not very +- * suited for NAT, as it has no protocol-specific part as port numbers. +- * +- * It has an optional key field, which may help us distinguishing two +- * connections between the same two hosts. +- * +- * GRE is defined in RFC 1701 and RFC 1702, as well as RFC 2784 +- * +- * PPTP is built on top of a modified version of GRE, and has a mandatory +- * field called "CallID", which serves us for the same purpose as the key +- * field in plain GRE. +- * +- * Documentation about PPTP can be found in RFC 2637 +- * +- * (C) 2000-2002 by Harald Welte +- * +- * Development of this code funded by Astaro AG (http://www.astaro.com/) +- * +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-MODULE_LICENSE("GPL"); +-MODULE_AUTHOR("Harald Welte "); +-MODULE_DESCRIPTION("Netfilter NAT protocol helper module for GRE"); +- +-#define DEBUGP(x, args...) +- +-/* is key in given range between min and max */ +-static int +-gre_in_range(const struct ip_conntrack_tuple *tuple, +- enum ip_nat_manip_type maniptype, +- const union ip_conntrack_manip_proto *min, +- const union ip_conntrack_manip_proto *max) +-{ +- return ntohl(tuple->src.u.gre.key) >= ntohl(min->gre.key) +- && ntohl(tuple->src.u.gre.key) <= ntohl(max->gre.key); +-} +- +-/* generate unique tuple ... */ +-static int +-gre_unique_tuple(struct ip_conntrack_tuple *tuple, +- const struct ip_nat_range *range, +- enum ip_nat_manip_type maniptype, +- const struct ip_conntrack *conntrack) +-{ +- u_int32_t min, i, range_size; +- u_int32_t key = 0, *keyptr; +- +- if (maniptype == IP_NAT_MANIP_SRC) +- keyptr = &tuple->src.u.gre.key; +- else +- keyptr = &tuple->dst.u.gre.key; +- +- if (!(range->flags & IP_NAT_RANGE_PROTO_SPECIFIED)) { +- +- switch (tuple->dst.u.gre.version) { +- case 0: +- DEBUGP("NATing GRE version 0 (ct=%p)\n", +- conntrack); +- min = 1; +- range_size = 0xffffffff; +- break; +- case GRE_VERSION_PPTP: +- DEBUGP("%p: NATing GRE PPTP\n", +- conntrack); +- min = 1; +- range_size = 0xffff; +- break; +- default: +- printk(KERN_WARNING "nat_gre: unknown GRE version\n"); +- return 0; +- break; +- } +- +- } else { +- min = ntohl(range->min.gre.key); +- range_size = ntohl(range->max.gre.key) - min + 1; +- } +- +- DEBUGP("min = %u, range_size = %u\n", min, range_size); +- +- for (i = 0; i < range_size; i++, key++) { +- *keyptr = htonl(min + key % range_size); +- if (!ip_nat_used_tuple(tuple, conntrack)) +- return 1; +- } +- +- DEBUGP("%p: no NAT mapping\n", conntrack); +- +- return 0; +-} +- +-/* manipulate a GRE packet according to maniptype */ +-static void +-gre_manip_pkt(struct iphdr *iph, size_t len, +- const struct ip_conntrack_manip *manip, +- enum ip_nat_manip_type maniptype) +-{ +- struct gre_hdr *greh = (struct gre_hdr *)((u_int32_t *)iph+iph->ihl); +- struct gre_hdr_pptp *pgreh = (struct gre_hdr_pptp *) greh; +- +- /* we only have destination manip of a packet, since 'source key' +- * is not present in the packet itself */ +- if (maniptype == IP_NAT_MANIP_DST) { +- /* key manipulation is always dest */ +- switch (greh->version) { +- case 0: +- if (!greh->key) { +- DEBUGP("can't nat GRE w/o key\n"); +- break; +- } +- if (greh->csum) { +- *(gre_csum(greh)) = +- ip_nat_cheat_check(~*(gre_key(greh)), +- manip->u.gre.key, +- *(gre_csum(greh))); +- } +- *(gre_key(greh)) = manip->u.gre.key; +- break; +- case GRE_VERSION_PPTP: +- DEBUGP("call_id -> 0x%04x\n", +- ntohl(manip->u.gre.key)); +- pgreh->call_id = htons(ntohl(manip->u.gre.key)); +- break; +- default: +- DEBUGP("can't nat unknown GRE version\n"); +- break; +- } +- } +-} +- +-/* print out a nat tuple */ +-static unsigned int +-gre_print(char *buffer, +- const struct ip_conntrack_tuple *match, +- const struct ip_conntrack_tuple *mask) +-{ +- unsigned int len = 0; +- +- if (mask->dst.u.gre.version) +- len += sprintf(buffer + len, "version=%d ", +- ntohs(match->dst.u.gre.version)); +- +- if (mask->dst.u.gre.protocol) +- len += sprintf(buffer + len, "protocol=0x%x ", +- ntohs(match->dst.u.gre.protocol)); +- +- if (mask->src.u.gre.key) +- len += sprintf(buffer + len, "srckey=0x%x ", +- ntohl(match->src.u.gre.key)); +- +- if (mask->dst.u.gre.key) +- len += sprintf(buffer + len, "dstkey=0x%x ", +- ntohl(match->src.u.gre.key)); +- +- return len; +-} +- +-/* print a range of keys */ +-static unsigned int +-gre_print_range(char *buffer, const struct ip_nat_range *range) +-{ +- if (range->min.gre.key != 0 +- || range->max.gre.key != 0xFFFF) { +- if (range->min.gre.key == range->max.gre.key) +- return sprintf(buffer, "key 0x%x ", +- ntohl(range->min.gre.key)); +- else +- return sprintf(buffer, "keys 0x%u-0x%u ", +- ntohl(range->min.gre.key), +- ntohl(range->max.gre.key)); +- } else +- return 0; +-} +- +-/* nat helper struct */ +-static struct ip_nat_protocol gre = +- { { NULL, NULL }, "GRE", IPPROTO_GRE, +- gre_manip_pkt, +- gre_in_range, +- gre_unique_tuple, +- gre_print, +- gre_print_range +- }; +- +-static int __init init(void) +-{ +- if (ip_nat_protocol_register(&gre)) +- return -EIO; +- +- return 0; +-} +- +-static void __exit fini(void) +-{ +- ip_nat_protocol_unregister(&gre); +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_standalone.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_standalone.c +--- src/linux/linux/net/ipv4/netfilter/ip_nat_standalone.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_standalone.c 2004-05-09 04:13:03.000000000 -0400 +@@ -37,7 +37,11 @@ + #include + #include + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + #define HOOKNAME(hooknum) ((hooknum) == NF_IP_POST_ROUTING ? "POST_ROUTING" \ + : ((hooknum) == NF_IP_PRE_ROUTING ? "PRE_ROUTING" \ +@@ -354,6 +358,5 @@ + EXPORT_SYMBOL(ip_nat_helper_unregister); + EXPORT_SYMBOL(ip_nat_cheat_check); + EXPORT_SYMBOL(ip_nat_mangle_tcp_packet); +-EXPORT_SYMBOL(ip_nat_mangle_udp_packet); + EXPORT_SYMBOL(ip_nat_used_tuple); + MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_nat_tftp.c src/linux/linux.stock/net/ipv4/netfilter/ip_nat_tftp.c +--- src/linux/linux/net/ipv4/netfilter/ip_nat_tftp.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_nat_tftp.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,186 +0,0 @@ +-/* +- * Licensed under GNU GPL version 2 Copyright Magnus Boden +- * Version: 0.0.7 +- * +- * Thu 21 Mar 2002 Harald Welte +- * - Port to newnat API +- * +- * This module currently supports DNAT: +- * iptables -t nat -A PREROUTING -d x.x.x.x -j DNAT --to-dest x.x.x.y +- * +- * and SNAT: +- * iptables -t nat -A POSTROUTING { -j MASQUERADE , -j SNAT --to-source x.x.x.x } +- * +- * It has not been tested with +- * -j SNAT --to-source x.x.x.x-x.x.x.y since I only have one external ip +- * If you do test this please let me know if it works or not. +- * +- */ +- +-#include +-#include +-#include +-#include +- +-#include +-#include +-#include +-#include +-#include +-#include +- +-MODULE_AUTHOR("Magnus Boden "); +-MODULE_DESCRIPTION("Netfilter NAT helper for tftp"); +-MODULE_LICENSE("GPL"); +- +-#define MAX_PORTS 8 +- +-static int ports[MAX_PORTS]; +-static int ports_c = 0; +-#ifdef MODULE_PARM +-MODULE_PARM(ports,"1-" __MODULE_STRING(MAX_PORTS) "i"); +-MODULE_PARM_DESC(ports, "port numbers of tftp servers"); +-#endif +- +-#define DEBUGP(format, args...) +-static unsigned int +-tftp_nat_help(struct ip_conntrack *ct, +- struct ip_conntrack_expect *exp, +- struct ip_nat_info *info, +- enum ip_conntrack_info ctinfo, +- unsigned int hooknum, +- struct sk_buff **pskb) +-{ +- int dir = CTINFO2DIR(ctinfo); +- struct iphdr *iph = (*pskb)->nh.iph; +- struct udphdr *udph = (void *)iph + iph->ihl * 4; +- struct tftphdr *tftph = (void *)udph + 8; +- struct ip_conntrack_tuple repl; +- +- if (!((hooknum == NF_IP_POST_ROUTING && dir == IP_CT_DIR_ORIGINAL) +- || (hooknum == NF_IP_PRE_ROUTING && dir == IP_CT_DIR_REPLY))) +- return NF_ACCEPT; +- +- if (!exp) { +- DEBUGP("no conntrack expectation to modify\n"); +- return NF_ACCEPT; +- } +- +- switch (ntohs(tftph->opcode)) { +- /* RRQ and WRQ works the same way */ +- case TFTP_OPCODE_READ: +- case TFTP_OPCODE_WRITE: +- repl = ct->tuplehash[IP_CT_DIR_REPLY].tuple; +- DEBUGP(""); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple); +- DUMP_TUPLE(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); +- DEBUGP("expecting: "); +- DUMP_TUPLE_RAW(&repl); +- DUMP_TUPLE_RAW(&exp->mask); +- ip_conntrack_change_expect(exp, &repl); +- break; +- default: +- DEBUGP("Unknown opcode\n"); +- } +- +- return NF_ACCEPT; +-} +- +-static unsigned int +-tftp_nat_expected(struct sk_buff **pskb, +- unsigned int hooknum, +- struct ip_conntrack *ct, +- struct ip_nat_info *info) +-{ +- const struct ip_conntrack *master = ct->master->expectant; +- const struct ip_conntrack_tuple *orig = +- &master->tuplehash[IP_CT_DIR_ORIGINAL].tuple; +- struct ip_nat_multi_range mr; +- +- IP_NF_ASSERT(info); +- IP_NF_ASSERT(master); +- IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum)))); +- +- mr.rangesize = 1; +- mr.range[0].flags = IP_NAT_RANGE_MAP_IPS; +- +- if (HOOK2MANIP(hooknum) == IP_NAT_MANIP_SRC) { +- mr.range[0].min_ip = mr.range[0].max_ip = orig->dst.ip; +- DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u " +- "newsrc: %u.%u.%u.%u\n", +- NIPQUAD((*pskb)->nh.iph->saddr), ntohs(udph->source), +- NIPQUAD((*pskb)->nh.iph->daddr), ntohs(udph->dest), +- NIPQUAD(orig->dst.ip)); +- } else { +- mr.range[0].min_ip = mr.range[0].max_ip = orig->src.ip; +- mr.range[0].min.udp.port = mr.range[0].max.udp.port = +- orig->src.u.udp.port; +- mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; +- +- DEBUGP("orig: %u.%u.%u.%u:%u <-> %u.%u.%u.%u:%u " +- "newdst: %u.%u.%u.%u:%u\n", +- NIPQUAD((*pskb)->nh.iph->saddr), ntohs(udph->source), +- NIPQUAD((*pskb)->nh.iph->daddr), ntohs(udph->dest), +- NIPQUAD(orig->src.ip), ntohs(orig->src.u.udp.port)); +- } +- +- return ip_nat_setup_info(ct,&mr,hooknum); +-} +- +-static struct ip_nat_helper tftp[MAX_PORTS]; +-static char tftp_names[MAX_PORTS][10]; +- +-static void fini(void) +-{ +- int i; +- +- for (i = 0 ; i < ports_c; i++) { +- DEBUGP("unregistering helper for port %d\n", ports[i]); +- ip_nat_helper_unregister(&tftp[i]); +- } +-} +- +-static int __init init(void) +-{ +- int i, ret; +- char *tmpname; +- +- if (!ports[0]) +- ports[0] = TFTP_PORT; +- +- for (i = 0 ; (i < MAX_PORTS) && ports[i] ; i++) { +- memset(&tftp[i], 0, sizeof(struct ip_nat_helper)); +- +- tftp[i].tuple.dst.protonum = IPPROTO_UDP; +- tftp[i].tuple.src.u.udp.port = htons(ports[i]); +- tftp[i].mask.dst.protonum = 0xFFFF; +- tftp[i].mask.src.u.udp.port = 0xFFFF; +- tftp[i].help = tftp_nat_help; +- tftp[i].flags = 0; +- tftp[i].me = THIS_MODULE; +- tftp[i].expect = tftp_nat_expected; +- +- tmpname = &tftp_names[i][0]; +- if (ports[i] == TFTP_PORT) +- sprintf(tmpname, "tftp"); +- else +- sprintf(tmpname, "tftp-%d", i); +- tftp[i].name = tmpname; +- +- DEBUGP("ip_nat_tftp: registering for port %d: name %s\n", +- ports[i], tftp[i].name); +- ret = ip_nat_helper_register(&tftp[i]); +- +- if (ret) { +- printk("ip_nat_tftp: unable to register for port %d\n", +- ports[i]); +- fini(); +- return ret; +- } +- ports_c++; +- } +- return ret; +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ip_pool.c src/linux/linux.stock/net/ipv4/netfilter/ip_pool.c +--- src/linux/linux/net/ipv4/netfilter/ip_pool.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ip_pool.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,328 +0,0 @@ +-/* Kernel module for IP pool management */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +-#define DP(format, args...) +- +-MODULE_LICENSE("GPL"); +- +-#define NR_POOL 16 +-static int nr_pool = NR_POOL;/* overwrite this when loading module */ +- +-struct ip_pool { +- u_int32_t first_ip; /* host byte order, included in range */ +- u_int32_t last_ip; /* host byte order, included in range */ +- void *members; /* the bitmap proper */ +- int nr_use; /* total nr. of tests through this */ +- int nr_match; /* total nr. of matches through this */ +- rwlock_t lock; +-}; +- +-static struct ip_pool *POOL; +- +-static inline struct ip_pool *lookup(ip_pool_t index) +-{ +- if (index < 0 || index >= nr_pool) { +- DP("ip_pool:lookup: bad index %d\n", index); +- return 0; +- } +- return POOL+index; +-} +- +-int ip_pool_match(ip_pool_t index, u_int32_t addr) +-{ +- struct ip_pool *pool = lookup(index); +- int res = 0; +- +- if (!pool || !pool->members) +- return 0; +- read_lock_bh(&pool->lock); +- if (pool->members) { +- if (addr >= pool->first_ip && addr <= pool->last_ip) { +- addr -= pool->first_ip; +- if (test_bit(addr, pool->members)) { +- res = 1; +-#ifdef CONFIG_IP_POOL_STATISTICS +- pool->nr_match++; +-#endif +- } +- } +-#ifdef CONFIG_IP_POOL_STATISTICS +- pool->nr_use++; +-#endif +- } +- read_unlock_bh(&pool->lock); +- return res; +-} +- +-static int pool_change(ip_pool_t index, u_int32_t addr, int isdel) +-{ +- struct ip_pool *pool; +- int res = -1; +- +- pool = lookup(index); +- if ( !pool || !pool->members +- || addr < pool->first_ip || addr > pool->last_ip) +- return -1; +- read_lock_bh(&pool->lock); +- if (pool->members && addr >= pool->first_ip && addr <= pool->last_ip) { +- addr -= pool->first_ip; +- res = isdel +- ? (0 != test_and_clear_bit(addr, pool->members)) +- : (0 != test_and_set_bit(addr, pool->members)); +- } +- read_unlock_bh(&pool->lock); +- return res; +-} +- +-int ip_pool_mod(ip_pool_t index, u_int32_t addr, int isdel) +-{ +- int res = pool_change(index,addr,isdel); +- +- if (!isdel) res = !res; +- return res; +-} +- +-static inline int bitmap_bytes(u_int32_t a, u_int32_t b) +-{ +- return 4*((((b-a+8)/8)+3)/4); +-} +- +-static inline int poolbytes(ip_pool_t index) +-{ +- struct ip_pool *pool = lookup(index); +- +- return pool ? bitmap_bytes(pool->first_ip, pool->last_ip) : 0; +-} +- +-static int setpool( +- struct sock *sk, +- int optval, +- void *user, +- unsigned int len +-) { +- struct ip_pool_request req; +- +- DP("ip_pool:setpool: optval=%d, user=%p, len=%d\n", optval, user, len); +- if (!capable(CAP_NET_ADMIN)) +- return -EPERM; +- if (optval != SO_IP_POOL) +- return -EBADF; +- if (len != sizeof(req)) +- return -EINVAL; +- if (copy_from_user(&req, user, sizeof(req)) != 0) +- return -EFAULT; +- printk("obsolete op - upgrade your ippool(8) utility.\n"); +- return -EINVAL; +-} +- +-static int getpool( +- struct sock *sk, +- int optval, +- void *user, +- int *len +-) { +- struct ip_pool_request req; +- struct ip_pool *pool; +- ip_pool_t i; +- int newbytes; +- void *newmembers; +- int res; +- +- DP("ip_pool:getpool: optval=%d, user=%p\n", optval, user); +- if (!capable(CAP_NET_ADMIN)) +- return -EINVAL; +- if (optval != SO_IP_POOL) +- return -EINVAL; +- if (*len != sizeof(req)) { +- return -EFAULT; +- } +- if (copy_from_user(&req, user, sizeof(req)) != 0) +- return -EFAULT; +- DP("ip_pool:getpool op=%d, index=%d\n", req.op, req.index); +- if (req.op < IP_POOL_BAD001) { +- printk("obsolete op - upgrade your ippool(8) utility.\n"); +- return -EFAULT; +- } +- switch(req.op) { +- case IP_POOL_HIGH_NR: +- DP("ip_pool HIGH_NR\n"); +- req.index = IP_POOL_NONE; +- for (i=0; imembers) +- return -EBADF; +- req.addr = htonl(pool->first_ip); +- req.addr2 = htonl(pool->last_ip); +- return copy_to_user(user, &req, sizeof(req)); +- case IP_POOL_USAGE: +- DP("ip_pool USE\n"); +- pool = lookup(req.index); +- if (!pool) +- return -EINVAL; +- if (!pool->members) +- return -EBADF; +- req.addr = pool->nr_use; +- req.addr2 = pool->nr_match; +- return copy_to_user(user, &req, sizeof(req)); +- case IP_POOL_TEST_ADDR: +- DP("ip_pool TEST 0x%08x\n", req.addr); +- pool = lookup(req.index); +- if (!pool) +- return -EINVAL; +- res = 0; +- read_lock_bh(&pool->lock); +- if (!pool->members) { +- DP("ip_pool TEST_ADDR no members in pool\n"); +- res = -EBADF; +- goto unlock_and_return_res; +- } +- req.addr = ntohl(req.addr); +- if (req.addr < pool->first_ip) { +- DP("ip_pool TEST_ADDR address < pool bounds\n"); +- res = -ERANGE; +- goto unlock_and_return_res; +- } +- if (req.addr > pool->last_ip) { +- DP("ip_pool TEST_ADDR address > pool bounds\n"); +- res = -ERANGE; +- goto unlock_and_return_res; +- } +- req.addr = (0 != test_bit((req.addr - pool->first_ip), +- pool->members)); +- read_unlock_bh(&pool->lock); +- return copy_to_user(user, &req, sizeof(req)); +- case IP_POOL_FLUSH: +- DP("ip_pool FLUSH not yet implemented.\n"); +- return -EBUSY; +- case IP_POOL_DESTROY: +- DP("ip_pool DESTROY not yet implemented.\n"); +- return -EBUSY; +- case IP_POOL_INIT: +- DP("ip_pool INIT 0x%08x-0x%08x\n", req.addr, req.addr2); +- pool = lookup(req.index); +- if (!pool) +- return -EINVAL; +- req.addr = ntohl(req.addr); +- req.addr2 = ntohl(req.addr2); +- if (req.addr > req.addr2) { +- DP("ip_pool INIT bad ip range\n"); +- return -EINVAL; +- } +- newbytes = bitmap_bytes(req.addr, req.addr2); +- newmembers = kmalloc(newbytes, GFP_KERNEL); +- if (!newmembers) { +- DP("ip_pool INIT out of mem for %d bytes\n", newbytes); +- return -ENOMEM; +- } +- memset(newmembers, 0, newbytes); +- write_lock_bh(&pool->lock); +- if (pool->members) { +- DP("ip_pool INIT pool %d exists\n", req.index); +- kfree(newmembers); +- res = -EBUSY; +- goto unlock_and_return_res; +- } +- pool->first_ip = req.addr; +- pool->last_ip = req.addr2; +- pool->nr_use = 0; +- pool->nr_match = 0; +- pool->members = newmembers; +- write_unlock_bh(&pool->lock); +- return 0; +- case IP_POOL_ADD_ADDR: +- DP("ip_pool ADD_ADDR 0x%08x\n", req.addr); +- req.addr = pool_change(req.index, ntohl(req.addr), 0); +- return copy_to_user(user, &req, sizeof(req)); +- case IP_POOL_DEL_ADDR: +- DP("ip_pool DEL_ADDR 0x%08x\n", req.addr); +- req.addr = pool_change(req.index, ntohl(req.addr), 1); +- return copy_to_user(user, &req, sizeof(req)); +- default: +- DP("ip_pool:getpool bad op %d\n", req.op); +- return -EINVAL; +- } +- return -EINVAL; +- +-unlock_and_return_res: +- if (pool) +- read_unlock_bh(&pool->lock); +- return res; +-} +- +-static struct nf_sockopt_ops so_pool +-= { { NULL, NULL }, PF_INET, +- SO_IP_POOL, SO_IP_POOL+1, &setpool, +- SO_IP_POOL, SO_IP_POOL+1, &getpool, +- 0, NULL }; +- +-MODULE_PARM(nr_pool, "i"); +- +-static int __init init(void) +-{ +- ip_pool_t i; +- int res; +- +- if (nr_pool < 1) { +- printk("ip_pool module init: bad nr_pool %d\n", nr_pool); +- return -EINVAL; +- } +- POOL = kmalloc(nr_pool * sizeof(*POOL), GFP_KERNEL); +- if (!POOL) { +- printk("ip_pool module init: out of memory for nr_pool %d\n", +- nr_pool); +- return -ENOMEM; +- } +- for (i=0; i + #include + ++#if 0 ++/* All the better to debug you with... */ ++#define static ++#define inline ++#endif + + /* Locking is simple: we assume at worst case there will be one packet + in user context and one from bottom halves (or soft irq if Alexey's +@@ -83,6 +88,7 @@ + { + /* Size per table */ + unsigned int size; ++ /* Number of entries: FIXME. --RR */ + unsigned int number; + /* Initial number of entries. Needed for module usage count */ + unsigned int initial_entries; +@@ -106,6 +112,11 @@ + #define TABLE_OFFSET(t,p) 0 + #endif + ++#if 0 ++#define down(x) do { printk("DOWN:%u:" #x "\n", __LINE__); down(x); } while(0) ++#define down_interruptible(x) ({ int __r; printk("DOWNi:%u:" #x "\n", __LINE__); __r = down_interruptible(x); if (__r != 0) printk("ABORT-DOWNi:%u\n", __LINE__); __r; }) ++#define up(x) do { printk("UP:%u:" #x "\n", __LINE__); up(x); } while(0) ++#endif + + /* Returns whether matches rule or not. */ + static inline int +@@ -408,6 +419,12 @@ + { + void *ret; + ++#if 0 ++ duprintf("find_inlist: searching for `%s' in %s.\n", ++ name, head == &ipt_target ? "ipt_target" ++ : head == &ipt_match ? "ipt_match" ++ : head == &ipt_tables ? "ipt_tables" : "UNKNOWN"); ++#endif + + *error = down_interruptible(mutex); + if (*error != 0) +@@ -745,6 +762,8 @@ + newinfo->underflow[h] = underflows[h]; + } + ++ /* FIXME: underflows must be unconditional, standard verdicts ++ < 0 (not IPT_RETURN). --RR */ + + /* Clear counters and comefrom */ + e->counters = ((struct ipt_counters) { 0, 0 }); +@@ -957,6 +976,7 @@ + goto free_counters; + } + ++ /* FIXME: use iterator macros --RR */ + /* ... then go back and fix counters and names */ + for (off = 0, num = 0; off < total_size; off += e->next_offset, num++){ + unsigned int i; +@@ -1134,6 +1154,14 @@ + const struct ipt_counters addme[], + unsigned int *i) + { ++#if 0 ++ duprintf("add_counter: Entry %u %lu/%lu + %lu/%lu\n", ++ *i, ++ (long unsigned int)e->counters.pcnt, ++ (long unsigned int)e->counters.bcnt, ++ (long unsigned int)addme[*i].pcnt, ++ (long unsigned int)addme[*i].bcnt); ++#endif + + ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt); + +@@ -1495,6 +1523,7 @@ + return 0; + } + ++ /* FIXME: Try tcp doff >> packet len against various stacks --RR */ + + #define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg)) + +@@ -1670,15 +1699,14 @@ + = { { NULL, NULL }, "icmp", &icmp_match, &icmp_checkentry, NULL }; + + #ifdef CONFIG_PROC_FS +-static inline int print_name(const char *i, ++static inline int print_name(const struct ipt_table *t, + off_t start_offset, char *buffer, int length, + off_t *pos, unsigned int *count) + { + if ((*count)++ >= start_offset) { + unsigned int namelen; + +- namelen = sprintf(buffer + *pos, "%s\n", +- i + sizeof(struct list_head)); ++ namelen = sprintf(buffer + *pos, "%s\n", t->name); + if (*pos + namelen > length) { + /* Stop iterating */ + return 1; +@@ -1696,7 +1724,7 @@ + if (down_interruptible(&ipt_mutex) != 0) + return 0; + +- LIST_FIND(&ipt_tables, print_name, void *, ++ LIST_FIND(&ipt_tables, print_name, struct ipt_table *, + offset, buffer, length, &pos, &count); + + up(&ipt_mutex); +@@ -1705,46 +1733,6 @@ + *start=(char *)((unsigned long)count-offset); + return pos; + } +- +-static int ipt_get_targets(char *buffer, char **start, off_t offset, int length) +-{ +- off_t pos = 0; +- unsigned int count = 0; +- +- if (down_interruptible(&ipt_mutex) != 0) +- return 0; +- +- LIST_FIND(&ipt_target, print_name, void *, +- offset, buffer, length, &pos, &count); +- +- up(&ipt_mutex); +- +- *start = (char *)((unsigned long)count - offset); +- return pos; +-} +- +-static int ipt_get_matches(char *buffer, char **start, off_t offset, int length) +-{ +- off_t pos = 0; +- unsigned int count = 0; +- +- if (down_interruptible(&ipt_mutex) != 0) +- return 0; +- +- LIST_FIND(&ipt_match, print_name, void *, +- offset, buffer, length, &pos, &count); +- +- up(&ipt_mutex); +- +- *start = (char *)((unsigned long)count - offset); +- return pos; +-} +- +-static struct { char *name; get_info_t *get_info; } ipt_proc_entry[] = +-{ { "ip_tables_names", ipt_get_tables }, +- { "ip_tables_targets", ipt_get_targets }, +- { "ip_tables_matches", ipt_get_matches }, +- { NULL, NULL} }; + #endif /*CONFIG_PROC_FS*/ + + static int __init init(void) +@@ -1770,20 +1758,14 @@ + #ifdef CONFIG_PROC_FS + { + struct proc_dir_entry *proc; +- int i; + +- for (i = 0; ipt_proc_entry[i].name; i++) { +- proc = proc_net_create(ipt_proc_entry[i].name, 0, +- ipt_proc_entry[i].get_info); ++ proc = proc_net_create("ip_tables_names", 0, ipt_get_tables); + if (!proc) { +- while (--i >= 0) +- proc_net_remove(ipt_proc_entry[i].name); + nf_unregister_sockopt(&ipt_sockopts); + return -ENOMEM; + } + proc->owner = THIS_MODULE; + } +- } + #endif + + printk("ip_tables: (C) 2000-2002 Netfilter core team\n"); +@@ -1794,11 +1776,7 @@ + { + nf_unregister_sockopt(&ipt_sockopts); + #ifdef CONFIG_PROC_FS +- { +- int i; +- for (i = 0; ipt_proc_entry[i].name; i++) +- proc_net_remove(ipt_proc_entry[i].name); +- } ++ proc_net_remove("ip_tables_names"); + #endif + } + +diff -Nurb src/linux/linux/net/ipv4/netfilter/ipchains_core.c src/linux/linux.stock/net/ipv4/netfilter/ipchains_core.c +--- src/linux/linux/net/ipv4/netfilter/ipchains_core.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ipchains_core.c 2004-05-09 04:13:03.000000000 -0400 +@@ -977,10 +977,17 @@ + || ftmp->ipfw.fw_dst.s_addr!=frwl->ipfw.fw_dst.s_addr + || ftmp->ipfw.fw_smsk.s_addr!=frwl->ipfw.fw_smsk.s_addr + || ftmp->ipfw.fw_dmsk.s_addr!=frwl->ipfw.fw_dmsk.s_addr ++#if 0 ++ || ftmp->ipfw.fw_flg!=frwl->ipfw.fw_flg ++#else + || ((ftmp->ipfw.fw_flg & ~IP_FW_F_MARKABS) + != (frwl->ipfw.fw_flg & ~IP_FW_F_MARKABS)) ++#endif + || ftmp->ipfw.fw_invflg!=frwl->ipfw.fw_invflg + || ftmp->ipfw.fw_proto!=frwl->ipfw.fw_proto ++#if 0 ++ || ftmp->ipfw.fw_mark!=frwl->ipfw.fw_mark ++#endif + || ftmp->ipfw.fw_redirpt!=frwl->ipfw.fw_redirpt + || ftmp->ipfw.fw_spts[0]!=frwl->ipfw.fw_spts[0] + || ftmp->ipfw.fw_spts[1]!=frwl->ipfw.fw_spts[1] +@@ -1566,6 +1573,7 @@ + ) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) ++ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ + int reset = 0; + #endif + struct ip_chain *i; +diff -Nurb src/linux/linux/net/ipv4/netfilter/ipfwadm_core.c src/linux/linux.stock/net/ipv4/netfilter/ipfwadm_core.c +--- src/linux/linux/net/ipv4/netfilter/ipfwadm_core.c 2003-10-14 04:09:33.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ipfwadm_core.c 2004-05-09 04:13:03.000000000 -0400 +@@ -20,7 +20,7 @@ + * license in recognition of the original copyright. + * -- Alan Cox. + * +- * $Id: ipfwadm_core.c,v 1.1.1.4 2003/10/14 08:09:33 sparq Exp $ ++ * $Id: ipfwadm_core.c,v 1.9.2.2 2002/01/24 15:50:42 davem Exp $ + * + * Ported from BSD to Linux, + * Alan Cox 22/Nov/1994. +@@ -1205,6 +1205,7 @@ + ) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) ++ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ + int reset = 0; + #endif + return ip_chain_procinfo(IP_FW_ACCT, buffer,start, offset,length, +@@ -1223,6 +1224,7 @@ + ) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) ++ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ + int reset = 0; + #endif + return ip_chain_procinfo(IP_FW_IN, buffer,start,offset,length, +@@ -1237,6 +1239,7 @@ + ) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) ++ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ + int reset = 0; + #endif + return ip_chain_procinfo(IP_FW_OUT, buffer,start,offset,length, +@@ -1251,6 +1254,7 @@ + ) + { + #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,29) ++ /* FIXME: No more `atomic' read and reset. Wonderful 8-( --RR */ + int reset = 0; + #endif + return ip_chain_procinfo(IP_FW_FWD, buffer,start,offset,length, +diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_ECN.c src/linux/linux.stock/net/ipv4/netfilter/ipt_ECN.c +--- src/linux/linux/net/ipv4/netfilter/ipt_ECN.c 2003-10-14 04:02:57.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ipt_ECN.c 2004-05-09 04:13:03.000000000 -0400 +@@ -87,8 +87,8 @@ + } + + if (diffs[0] != *tcpflags) { +- diffs[0] = diffs[0] ^ 0xFFFF; +- diffs[1] = *tcpflags; ++ diffs[0] = htons(diffs[0]) ^ 0xFFFF; ++ diffs[1] = htons(*tcpflags); + tcph->check = csum_fold(csum_partial((char *)diffs, + sizeof(diffs), + tcph->check^0xFFFF)); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_LOG.c src/linux/linux.stock/net/ipv4/netfilter/ipt_LOG.c +--- src/linux/linux/net/ipv4/netfilter/ipt_LOG.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ipt_LOG.c 2004-05-09 04:13:03.000000000 -0400 +@@ -14,11 +14,15 @@ + #include + #include + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + struct esphdr { + __u32 spi; +-}; ++}; /* FIXME evil kludge */ + + /* Use lock to serialize, so printks don't overlap */ + static spinlock_t log_lock = SPIN_LOCK_UNLOCKED; +diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_REJECT.c src/linux/linux.stock/net/ipv4/netfilter/ipt_REJECT.c +--- src/linux/linux/net/ipv4/netfilter/ipt_REJECT.c 2003-07-04 04:12:31.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ipt_REJECT.c 2004-05-09 04:13:03.000000000 -0400 +@@ -6,8 +6,6 @@ + #include + #include + #include +-#include +-#include + #include + #include + #include +@@ -16,7 +14,11 @@ + #include + #include + ++#if 0 ++#define DEBUGP printk ++#else + #define DEBUGP(format, args...) ++#endif + + /* If the original packet is part of a connection, but the connection + is not confirmed, our manufactured reply will not be associated +@@ -155,7 +157,6 @@ + static void send_unreach(struct sk_buff *skb_in, int code) + { + struct iphdr *iph; +- struct udphdr *udph; + struct icmphdr *icmph; + struct sk_buff *nskb; + u32 saddr; +@@ -167,6 +168,7 @@ + if (!rt) + return; + ++ /* FIXME: Use sysctl number. --RR */ + if (!xrlim_allow(&rt->u.dst, 1*HZ)) + return; + +@@ -184,19 +186,6 @@ + if (iph->frag_off&htons(IP_OFFSET)) + return; + +- /* if UDP checksum is set, verify it's correct */ +- if (iph->protocol == IPPROTO_UDP +- && skb_in->tail-(u8*)iph >= sizeof(struct udphdr)) { +- int datalen = skb_in->len - (iph->ihl<<2); +- udph = (struct udphdr *)((char *)iph + (iph->ihl<<2)); +- if (udph->check +- && csum_tcpudp_magic(iph->saddr, iph->daddr, +- datalen, IPPROTO_UDP, +- csum_partial((char *)udph, datalen, +- 0)) != 0) +- return; +- } +- + /* If we send an ICMP error to an ICMP error a mess would result.. */ + if (iph->protocol == IPPROTO_ICMP + && skb_in->tail-(u8*)iph >= sizeof(struct icmphdr)) { +@@ -271,6 +260,7 @@ + /* Copy as much of original packet as will fit */ + data = skb_put(nskb, + length - sizeof(struct iphdr) - sizeof(struct icmphdr)); ++ /* FIXME: won't work with nonlinear skbs --RR */ + memcpy(data, skb_in->nh.iph, + length - sizeof(struct iphdr) - sizeof(struct icmphdr)); + icmph->checksum = ip_compute_csum((unsigned char *)icmph, +diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_ULOG.c src/linux/linux.stock/net/ipv4/netfilter/ipt_ULOG.c +--- src/linux/linux/net/ipv4/netfilter/ipt_ULOG.c 2003-07-04 04:12:32.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ipt_ULOG.c 2004-05-09 04:13:03.000000000 -0400 +@@ -12,7 +12,6 @@ + * module loadtime -HW + * 2002/07/07 remove broken nflog_rcv() function -HW + * 2002/08/29 fix shifted/unshifted nlgroup bug -HW +- * 2002/10/30 fix uninitialized mac_len field - + * + * Released under the terms of the GPL + * +@@ -32,7 +31,7 @@ + * Specify, after how many clock ticks (intel: 100 per second) the queue + * should be flushed even if it is not full yet. + * +- * ipt_ULOG.c,v 1.22 2002/10/30 09:07:31 laforge Exp ++ * ipt_ULOG.c,v 1.21 2002/08/29 10:54:34 laforge Exp + */ + + #include +@@ -60,7 +59,12 @@ + #define ULOG_NL_EVENT 111 /* Harald's favorite number */ + #define ULOG_MAXNLGROUPS 32 /* numer of nlgroups */ + ++#if 0 ++#define DEBUGP(format, args...) printk(__FILE__ ":" __FUNCTION__ ":" \ ++ format, ## args) ++#else + #define DEBUGP(format, args...) ++#endif + + #define PRINTR(format, args...) do { if (net_ratelimit()) printk(format, ## args); } while (0) + +@@ -220,8 +224,7 @@ + && in->hard_header_len <= ULOG_MAC_LEN) { + memcpy(pm->mac, (*pskb)->mac.raw, in->hard_header_len); + pm->mac_len = in->hard_header_len; +- } else +- pm->mac_len = 0; ++ } + + if (in) + strncpy(pm->indev_name, in->name, sizeof(pm->indev_name)); +diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_multiport.c src/linux/linux.stock/net/ipv4/netfilter/ipt_multiport.c +--- src/linux/linux/net/ipv4/netfilter/ipt_multiport.c 2003-07-04 04:12:32.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ipt_multiport.c 2004-05-09 04:13:03.000000000 -0400 +@@ -8,7 +8,11 @@ + #include + #include + ++#if 0 ++#define duprintf(format, args...) printk(format , ## args) ++#else + #define duprintf(format, args...) ++#endif + + /* Returns 1 if the port is matched by the test, 0 otherwise. */ + static inline int +@@ -74,7 +78,7 @@ + + /* Must specify proto == TCP/UDP, no unknown flags or bad count */ + return (ip->proto == IPPROTO_TCP || ip->proto == IPPROTO_UDP) +- && !(ip->invflags & IPT_INV_PROTO) ++ && !(ip->flags & IPT_INV_PROTO) + && matchsize == IPT_ALIGN(sizeof(struct ipt_multiport)) + && (multiinfo->flags == IPT_MULTIPORT_SOURCE + || multiinfo->flags == IPT_MULTIPORT_DESTINATION +diff -Nurb src/linux/linux/net/ipv4/netfilter/ipt_pool.c src/linux/linux.stock/net/ipv4/netfilter/ipt_pool.c +--- src/linux/linux/net/ipv4/netfilter/ipt_pool.c 2003-07-04 04:12:32.000000000 -0400 ++++ src/linux/linux.stock/net/ipv4/netfilter/ipt_pool.c 1969-12-31 19:00:00.000000000 -0500 +@@ -1,71 +0,0 @@ +-/* Kernel module to match an IP address pool. */ +- +-#include +-#include +-#include +- +-#include +-#include +-#include +- +-static inline int match_pool( +- ip_pool_t index, +- __u32 addr, +- int inv +-) { +- if (ip_pool_match(index, ntohl(addr))) +- inv = !inv; +- return inv; +-} +- +-static int match( +- const struct sk_buff *skb, +- const struct net_device *in, +- const struct net_device *out, +- const void *matchinfo, +- int offset, +- const void *hdr, +- u_int16_t datalen, +- int *hotdrop +-) { +- const struct ipt_pool_info *info = matchinfo; +- const struct iphdr *iph = skb->nh.iph; +- +- if (info->src != IP_POOL_NONE && !match_pool(info->src, iph->saddr, +- info->flags&IPT_POOL_INV_SRC)) +- return 0; +- +- if (info->dst != IP_POOL_NONE && !match_pool(info->dst, iph->daddr, +- info->flags&IPT_POOL_INV_DST)) +- return 0; +- +- return 1; +-} +- +-static int checkentry( +- const char *tablename, +- const struct ipt_ip *ip, +- void *matchinfo, +- unsigned int matchsize, +- unsigned int hook_mask +-) { +- if (matchsize != IPT_ALIGN(sizeof(struct ipt_pool_info))) +- return 0; +- return 1; +-} +- +-static struct ipt_match pool_match +-= { { NULL, NULL }, "pool", &match, &checkentry, NULL, THIS_MODULE }; +- +-static int __init init(void) +-{ +- return ipt_register_match(&pool_match); +-} +- +-static void __exit fini(void) +-{ +- ipt_unregister_match(&pool_match); +-} +- +-module_init(init); +-module_exit(fini); +diff -Nurb src/linux/linux/net/ipv6/mcast.c src/linux/linux.stock/net/ipv6/mcast.c +--- src/linux/linux/net/ipv6/mcast.c 2003-10-14 04:09:34.000000000 -0400 ++++ src/linux/linux.stock/net/ipv6/mcast.c 2004-05-09 04:13:22.000000000 -0400 +@@ -5,7 +5,7 @@ + * Authors: + * Pedro Roque + * +- * $Id: mcast.c,v 1.1.1.4 2003/10/14 08:09:34 sparq Exp $ ++ * $Id: mcast.c,v 1.38 2001/08/15 07:36:31 davem Exp $ + * + * Based on linux/ipv4/igmp.c and linux/ipv4/ip_sockglue.c + * diff --git a/obsolete-buildroot/sources/openwrt/kernel/patches/110-sch_htb.patch b/obsolete-buildroot/sources/openwrt/kernel/patches/110-sch_htb.patch new file mode 100644 index 0000000000..f74168aeea --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/kernel/patches/110-sch_htb.patch @@ -0,0 +1,570 @@ +--- src/linux/linux/net/sched/sch_htb.c 2003-10-14 01:09:35.000000000 -0700 ++++ src/linux/linux.2.4.26/net/sched/sch_htb.c 2004-05-10 00:05:51.000000000 -0700 +@@ -9,6 +9,8 @@ + * Authors: Martin Devera, + * + * Credits (in time order) for older HTB versions: ++ * Stef Coene ++ * HTB support at LARTC mailing list + * Ondrej Kraus, + * found missing INIT_QDISC(htb) + * Vladimir Smelhaus, Aamer Akhter, Bert Hubert +@@ -17,9 +19,13 @@ + * code review and helpful comments on shaping + * Tomasz Wrona, + * created test case so that I was able to fix nasty bug ++ * Wilfried Weissmann ++ * spotted bug in dequeue code and helped with fix ++ * Jiri Fojtasek ++ * fixed requeue routine + * and many others. thanks. + * +- * $Id: sch_htb.c,v 1.1.1.4 2003/10/14 08:09:35 sparq Exp $ ++ * $Id: sch_htb.c,v 1.25 2003/12/07 11:08:25 devik Exp devik $ + */ + #include + #include +@@ -71,16 +77,12 @@ + #define HTB_HYSTERESIS 1/* whether to use mode hysteresis for speedup */ + #define HTB_QLOCK(S) spin_lock_bh(&(S)->dev->queue_lock) + #define HTB_QUNLOCK(S) spin_unlock_bh(&(S)->dev->queue_lock) +-#define HTB_VER 0x30007 /* major must be matched with number suplied by TC as version */ ++#define HTB_VER 0x30010 /* major must be matched with number suplied by TC as version */ + + #if HTB_VER >> 16 != TC_HTB_PROTOVER + #error "Mismatched sch_htb.c and pkt_sch.h" + #endif + +-/* temporary debug defines to be removed after beta stage */ +-#define DEVIK_MEND(N) +-#define DEVIK_MSTART(N) +- + /* debugging support; S is subsystem, these are defined: + 0 - netlink messages + 1 - enqueue +@@ -100,13 +102,16 @@ + from LSB + */ + #ifdef HTB_DEBUG +-#define HTB_DBG(S,L,FMT,ARG...) if (((q->debug>>(2*S))&3) >= L) \ ++#define HTB_DBG_COND(S,L) (((q->debug>>(2*S))&3) >= L) ++#define HTB_DBG(S,L,FMT,ARG...) if (HTB_DBG_COND(S,L)) \ + printk(KERN_DEBUG FMT,##ARG) + #define HTB_CHCL(cl) BUG_TRAP((cl)->magic == HTB_CMAGIC) + #define HTB_PASSQ q, + #define HTB_ARGQ struct htb_sched *q, + #define static ++#undef __inline__ + #define __inline__ ++#undef inline + #define inline + #define HTB_CMAGIC 0xFEFAFEF1 + #define htb_safe_rb_erase(N,R) do { BUG_TRAP((N)->rb_color != -1); \ +@@ -114,6 +119,7 @@ + rb_erase(N,R); \ + (N)->rb_color = -1; } while (0) + #else ++#define HTB_DBG_COND(S,L) (0) + #define HTB_DBG(S,L,FMT,ARG...) + #define HTB_PASSQ + #define HTB_ARGQ +@@ -219,6 +225,9 @@ + /* time of nearest event per level (row) */ + unsigned long near_ev_cache[TC_HTB_MAXDEPTH]; + ++ /* cached value of jiffies in dequeue */ ++ unsigned long jiffies; ++ + /* whether we hit non-work conserving class during this dequeue; we use */ + int nwc_hit; /* this to disable mindelay complaint in dequeue */ + +@@ -297,7 +306,7 @@ + rules in it */ + if (skb->priority == sch->handle) + return HTB_DIRECT; /* X:0 (direct flow) selected */ +- if ((cl = htb_find(skb->priority,sch)) != NULL) ++ if ((cl = htb_find(skb->priority,sch)) != NULL && cl->level == 0) + return cl; + + tcf = q->filter_list; +@@ -338,7 +347,7 @@ + static void htb_debug_dump (struct htb_sched *q) + { + int i,p; +- printk(KERN_DEBUG "htb*g j=%lu\n",jiffies); ++ printk(KERN_DEBUG "htb*g j=%lu lj=%lu\n",jiffies,q->jiffies); + /* rows */ + for (i=TC_HTB_MAXDEPTH-1;i>=0;i--) { + printk(KERN_DEBUG "htb*r%d m=%x",i,q->row_mask[i]); +@@ -421,26 +430,24 @@ + if ((delay <= 0 || delay > cl->mbuffer) && net_ratelimit()) + printk(KERN_ERR "HTB: suspicious delay in wait_tree d=%ld cl=%X h=%d\n",delay,cl->classid,debug_hint); + #endif +- DEVIK_MSTART(9); +- cl->pq_key = jiffies + PSCHED_US2JIFFIE(delay); +- if (cl->pq_key == jiffies) ++ cl->pq_key = q->jiffies + PSCHED_US2JIFFIE(delay); ++ if (cl->pq_key == q->jiffies) + cl->pq_key++; + + /* update the nearest event cache */ +- if (q->near_ev_cache[cl->level] - cl->pq_key < 0x80000000) ++ if (time_after(q->near_ev_cache[cl->level], cl->pq_key)) + q->near_ev_cache[cl->level] = cl->pq_key; + + while (*p) { + struct htb_class *c; parent = *p; + c = rb_entry(parent, struct htb_class, pq_node); +- if (cl->pq_key - c->pq_key < 0x80000000) ++ if (time_after_eq(cl->pq_key, c->pq_key)) + p = &parent->rb_right; + else + p = &parent->rb_left; + } + rb_link_node(&cl->pq_node, parent, p); + rb_insert_color(&cl->pq_node, &q->wait_pq[cl->level]); +- DEVIK_MEND(9); + } + + /** +@@ -453,12 +460,14 @@ + { + rb_node_t *p; + if ((*n)->rb_right) { ++ /* child at right. use it or its leftmost ancestor */ + *n = (*n)->rb_right; + while ((*n)->rb_left) + *n = (*n)->rb_left; + return; + } + while ((p = (*n)->rb_parent) != NULL) { ++ /* if we've arrived from left child then we have next node */ + if (p->rb_left == *n) break; + *n = p; + } +@@ -602,7 +611,7 @@ + long toks; + + if ((toks = (cl->ctokens + *diff)) < ( +-#ifdef HTB_HYSTERESIS ++#if HTB_HYSTERESIS + cl->cmode != HTB_CANT_SEND ? -cl->cbuffer : + #endif + 0)) { +@@ -610,7 +619,7 @@ + return HTB_CANT_SEND; + } + if ((toks = (cl->tokens + *diff)) >= ( +-#ifdef HTB_HYSTERESIS ++#if HTB_HYSTERESIS + cl->cmode == HTB_CAN_SEND ? -cl->buffer : + #endif + 0)) +@@ -689,7 +698,6 @@ + struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_class *cl = htb_classify(skb,sch); + +- DEVIK_MSTART(0); + if (cl == HTB_DIRECT || !cl) { + /* enqueue to helper queue */ + if (q->direct_queue.qlen < q->direct_qlen && cl) { +@@ -698,25 +706,20 @@ + } else { + kfree_skb (skb); + sch->stats.drops++; +- DEVIK_MEND(0); + return NET_XMIT_DROP; + } + } else if (cl->un.leaf.q->enqueue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) { + sch->stats.drops++; + cl->stats.drops++; +- DEVIK_MEND(0); + return NET_XMIT_DROP; + } else { + cl->stats.packets++; cl->stats.bytes += skb->len; +- DEVIK_MSTART(1); + htb_activate (q,cl); +- DEVIK_MEND(1); + } + + sch->q.qlen++; + sch->stats.packets++; sch->stats.bytes += skb->len; +- HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",cl?cl->classid:0,skb); +- DEVIK_MEND(0); ++ HTB_DBG(1,1,"htb_enq_ok cl=%X skb=%p\n",(cl && cl != HTB_DIRECT)?cl->classid:0,skb); + return NET_XMIT_SUCCESS; + } + +@@ -725,16 +728,18 @@ + { + struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_class *cl = htb_classify(skb,sch); ++ struct sk_buff *tskb; + + if (cl == HTB_DIRECT || !cl) { + /* enqueue to helper queue */ + if (q->direct_queue.qlen < q->direct_qlen && cl) { +- __skb_queue_tail(&q->direct_queue, skb); +- q->direct_pkts++; ++ __skb_queue_head(&q->direct_queue, skb); + } else { +- kfree_skb (skb); +- sch->stats.drops++; +- return NET_XMIT_DROP; ++ __skb_queue_head(&q->direct_queue, skb); ++ tskb = __skb_dequeue_tail(&q->direct_queue); ++ kfree_skb (tskb); ++ sch->stats.drops++; ++ return NET_XMIT_CN; + } + } else if (cl->un.leaf.q->ops->requeue(skb, cl->un.leaf.q) != NET_XMIT_SUCCESS) { + sch->stats.drops++; +@@ -744,7 +749,7 @@ + htb_activate (q,cl); + + sch->q.qlen++; +- HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",cl?cl->classid:0,skb); ++ HTB_DBG(1,1,"htb_req_ok cl=%X skb=%p\n",(cl && cl != HTB_DIRECT)?cl->classid:0,skb); + return NET_XMIT_SUCCESS; + } + +@@ -819,7 +824,7 @@ + cl->classid, diff, + (unsigned long long) q->now, + (unsigned long long) cl->t_c, +- jiffies); ++ q->jiffies); + diff = 1000; + } + #endif +@@ -862,6 +867,7 @@ + * + * Scans event queue for pending events and applies them. Returns jiffies to + * next pending event (0 for no event in pq). ++ * Note: Aplied are events whose have cl->pq_key <= jiffies. + */ + static long htb_do_events(struct htb_sched *q,int level) + { +@@ -876,9 +882,9 @@ + while (p->rb_left) p = p->rb_left; + + cl = rb_entry(p, struct htb_class, pq_node); +- if (cl->pq_key - (jiffies+1) < 0x80000000) { +- HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - jiffies); +- return cl->pq_key - jiffies; ++ if (time_after(cl->pq_key, q->jiffies)) { ++ HTB_DBG(8,3,"htb_do_ev_ret delay=%ld\n",cl->pq_key - q->jiffies); ++ return cl->pq_key - q->jiffies; + } + htb_safe_rb_erase(p,q->wait_pq+level); + diff = PSCHED_TDIFF_SAFE(q->now, cl->t_c, (u32)cl->mbuffer, 0); +@@ -889,7 +895,7 @@ + cl->classid, diff, + (unsigned long long) q->now, + (unsigned long long) cl->t_c, +- jiffies); ++ q->jiffies); + diff = 1000; + } + #endif +@@ -916,6 +922,7 @@ + rb_node_t **pptr; + } stk[TC_HTB_MAXDEPTH],*sp = stk; + ++ BUG_TRAP(tree->rb_node); + sp->root = tree->rb_node; + sp->pptr = pptr; + +@@ -949,16 +956,36 @@ + htb_dequeue_tree(struct htb_sched *q,int prio,int level) + { + struct sk_buff *skb = NULL; +- //struct htb_sched *q = (struct htb_sched *)sch->data; + struct htb_class *cl,*start; + /* look initial class up in the row */ +- DEVIK_MSTART(6); + start = cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio); + + do { +- BUG_TRAP(cl && cl->un.leaf.q->q.qlen); if (!cl) return NULL; ++next: ++ BUG_TRAP(cl); ++ if (!cl) return NULL; + HTB_DBG(4,1,"htb_deq_tr prio=%d lev=%d cl=%X defic=%d\n", + prio,level,cl->classid,cl->un.leaf.deficit[level]); ++ ++ /* class can be empty - it is unlikely but can be true if leaf ++ qdisc drops packets in enqueue routine or if someone used ++ graft operation on the leaf since last dequeue; ++ simply deactivate and skip such class */ ++ if (unlikely(cl->un.leaf.q->q.qlen == 0)) { ++ struct htb_class *next; ++ htb_deactivate(q,cl); ++ ++ /* row/level might become empty */ ++ if ((q->row_mask[level] & (1 << prio)) == 0) ++ return NULL; ++ ++ next = htb_lookup_leaf (q->row[level]+prio, ++ prio,q->ptr[level]+prio); ++ if (cl == start) /* fix start if we just deleted it */ ++ start = next; ++ cl = next; ++ goto next; ++ } + + if (likely((skb = cl->un.leaf.q->dequeue(cl->un.leaf.q)) != NULL)) + break; +@@ -971,8 +998,6 @@ + cl = htb_lookup_leaf (q->row[level]+prio,prio,q->ptr[level]+prio); + } while (cl != start); + +- DEVIK_MEND(6); +- DEVIK_MSTART(7); + if (likely(skb != NULL)) { + if ((cl->un.leaf.deficit[level] -= skb->len) < 0) { + HTB_DBG(4,2,"htb_next_cl oldptr=%p quant_add=%d\n", +@@ -984,11 +1009,8 @@ + gives us slightly better performance */ + if (!cl->un.leaf.q->q.qlen) + htb_deactivate (q,cl); +- DEVIK_MSTART(8); + htb_charge_class (q,cl,level,skb->len); +- DEVIK_MEND(8); + } +- DEVIK_MEND(7); + return skb; + } + +@@ -1002,9 +1024,8 @@ + printk(KERN_INFO "HTB delay %ld > 5sec\n", delay); + delay = 5*HZ; + } +- del_timer(&q->timer); +- q->timer.expires = jiffies + delay; +- add_timer(&q->timer); ++ /* why don't use jiffies here ? because expires can be in past */ ++ mod_timer(&q->timer, q->jiffies + delay); + sch->flags |= TCQ_F_THROTTLED; + sch->stats.overlimits++; + HTB_DBG(3,1,"htb_deq t_delay=%ld\n",delay); +@@ -1016,7 +1037,11 @@ + struct htb_sched *q = (struct htb_sched *)sch->data; + int level; + long min_delay; ++#ifdef HTB_DEBUG ++ int evs_used = 0; ++#endif + ++ q->jiffies = jiffies; + HTB_DBG(3,1,"htb_deq dircnt=%d qlen=%d\n",skb_queue_len(&q->direct_queue), + sch->q.qlen); + +@@ -1027,27 +1052,26 @@ + return skb; + } + +- DEVIK_MSTART(2); + if (!sch->q.qlen) goto fin; + PSCHED_GET_TIME(q->now); + +- min_delay = HZ*5; ++ min_delay = LONG_MAX; + q->nwc_hit = 0; + for (level = 0; level < TC_HTB_MAXDEPTH; level++) { + /* common case optimization - skip event handler quickly */ + int m; + long delay; +- DEVIK_MSTART(3); +- if (jiffies - q->near_ev_cache[level] < 0x80000000 || 0) { ++ if (time_after_eq(q->jiffies, q->near_ev_cache[level])) { + delay = htb_do_events(q,level); +- q->near_ev_cache[level] += delay ? delay : HZ; ++ q->near_ev_cache[level] = q->jiffies + (delay ? delay : HZ); ++#ifdef HTB_DEBUG ++ evs_used++; ++#endif + } else +- delay = q->near_ev_cache[level] - jiffies; ++ delay = q->near_ev_cache[level] - q->jiffies; + + if (delay && min_delay > delay) + min_delay = delay; +- DEVIK_MEND(3); +- DEVIK_MSTART(5); + m = ~q->row_mask[level]; + while (m != (int)(-1)) { + int prio = ffz (m); +@@ -1056,29 +1080,29 @@ + if (likely(skb != NULL)) { + sch->q.qlen--; + sch->flags &= ~TCQ_F_THROTTLED; +- DEVIK_MEND(5); + goto fin; + } + } +- DEVIK_MEND(5); + } +- DEVIK_MSTART(4); + #ifdef HTB_DEBUG +- if (!q->nwc_hit && min_delay >= 5*HZ && net_ratelimit()) { +- printk(KERN_ERR "HTB: mindelay=%ld, report it please !\n",min_delay); +- htb_debug_dump(q); ++ if (!q->nwc_hit && min_delay >= 10*HZ && net_ratelimit()) { ++ if (min_delay == LONG_MAX) { ++ printk(KERN_ERR "HTB: dequeue bug (%d,%lu,%lu), report it please !\n", ++ evs_used,q->jiffies,jiffies); ++ htb_debug_dump(q); ++ } else ++ printk(KERN_WARNING "HTB: mindelay=%ld, some class has " ++ "too small rate\n",min_delay); + } + #endif +- htb_delay_by (sch,min_delay); +- DEVIK_MEND(4); ++ htb_delay_by (sch,min_delay > 5*HZ ? 5*HZ : min_delay); + fin: +- HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,jiffies,skb); +- DEVIK_MEND(2); ++ HTB_DBG(3,1,"htb_deq_end %s j=%lu skb=%p\n",sch->dev->name,q->jiffies,skb); + return skb; + } + + /* try to drop from each class (by prio) until one succeed */ +-static int htb_drop(struct Qdisc* sch) ++static unsigned int htb_drop(struct Qdisc* sch) + { + struct htb_sched *q = (struct htb_sched *)sch->data; + int prio; +@@ -1086,14 +1110,15 @@ + for (prio = TC_HTB_NUMPRIO - 1; prio >= 0; prio--) { + struct list_head *p; + list_for_each (p,q->drops+prio) { +- struct htb_class *cl = list_entry(p,struct htb_class, +- un.leaf.drop_list); ++ struct htb_class *cl = list_entry(p, struct htb_class, ++ un.leaf.drop_list); ++ unsigned int len; + if (cl->un.leaf.q->ops->drop && +- cl->un.leaf.q->ops->drop(cl->un.leaf.q)) { ++ (len = cl->un.leaf.q->ops->drop(cl->un.leaf.q))) { + sch->q.qlen--; + if (!cl->un.leaf.q->q.qlen) + htb_deactivate (q,cl); +- return 1; ++ return len; + } + } + } +@@ -1208,7 +1233,8 @@ + gopt.direct_pkts = q->direct_pkts; + + #ifdef HTB_DEBUG +- htb_debug_dump(q); ++ if (HTB_DBG_COND(0,2)) ++ htb_debug_dump(q); + #endif + gopt.version = HTB_VER; + gopt.rate2quantum = q->rate2quantum; +@@ -1289,6 +1315,9 @@ + return -ENOBUFS; + sch_tree_lock(sch); + if ((*old = xchg(&cl->un.leaf.q, new)) != NULL) { ++ if (cl->prio_activity) ++ htb_deactivate ((struct htb_sched*)sch->data,cl); ++ + /* TODO: is it correct ? Why CBQ doesn't do it ? */ + sch->q.qlen -= (*old)->q.qlen; + qdisc_reset(*old); +@@ -1323,7 +1352,7 @@ + + while ((tp = *fl) != NULL) { + *fl = tp->next; +- tp->ops->destroy(tp); ++ tcf_destroy(tp); + } + } + +@@ -1371,11 +1400,16 @@ + #ifdef HTB_RATECM + del_timer_sync (&q->rttim); + #endif ++ /* This line used to be after htb_destroy_class call below ++ and surprisingly it worked in 2.4. But it must precede it ++ because filter need its target class alive to be able to call ++ unbind_filter on it (without Oops). */ ++ htb_destroy_filters(&q->filter_list); ++ + while (!list_empty(&q->root)) + htb_destroy_class (sch,list_entry(q->root.next, + struct htb_class,sibling)); + +- htb_destroy_filters(&q->filter_list); + __skb_queue_purge(&q->direct_queue); + MOD_DEC_USE_COUNT; + } +@@ -1438,12 +1472,13 @@ + parent = parentid == TC_H_ROOT ? NULL : htb_find (parentid,sch); + + hopt = RTA_DATA(tb[TCA_HTB_PARMS-1]); +- HTB_DBG(0,1,"htb_chg cl=%p, clid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum); ++ HTB_DBG(0,1,"htb_chg cl=%p(%X), clid=%X, parid=%X, opt/prio=%d, rate=%u, buff=%d, quant=%d\n", cl,cl?cl->classid:0,classid,parentid,(int)hopt->prio,hopt->rate.rate,hopt->buffer,hopt->quantum); + rtab = qdisc_get_rtab(&hopt->rate, tb[TCA_HTB_RTAB-1]); + ctab = qdisc_get_rtab(&hopt->ceil, tb[TCA_HTB_CTAB-1]); + if (!rtab || !ctab) goto failure; + + if (!cl) { /* new class */ ++ struct Qdisc *new_q; + /* check for valid classid */ + if (!classid || TC_H_MAJ(classid^sch->handle) || htb_find(classid,sch)) + goto failure; +@@ -1467,6 +1502,10 @@ + cl->magic = HTB_CMAGIC; + #endif + ++ /* create leaf qdisc early because it uses kmalloc(GFP_KERNEL) ++ so that can't be used inside of sch_tree_lock ++ -- thanks to Karlis Peisenieks */ ++ new_q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops); + sch_tree_lock(sch); + if (parent && !parent->level) { + /* turn parent into inner node */ +@@ -1485,8 +1524,7 @@ + memset (&parent->un.inner,0,sizeof(parent->un.inner)); + } + /* leaf (we) needs elementary qdisc */ +- if (!(cl->un.leaf.q = qdisc_create_dflt(sch->dev, &pfifo_qdisc_ops))) +- cl->un.leaf.q = &noop_qdisc; ++ cl->un.leaf.q = new_q ? new_q : &noop_qdisc; + + cl->classid = classid; cl->parent = parent; + +@@ -1514,11 +1552,11 @@ + if (!cl->level) { + cl->un.leaf.quantum = rtab->rate.rate / q->rate2quantum; + if (!hopt->quantum && cl->un.leaf.quantum < 1000) { +- printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.", cl->classid); ++ printk(KERN_WARNING "HTB: quantum of class %X is small. Consider r2q change.\n", cl->classid); + cl->un.leaf.quantum = 1000; + } + if (!hopt->quantum && cl->un.leaf.quantum > 200000) { +- printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.", cl->classid); ++ printk(KERN_WARNING "HTB: quantum of class %X is big. Consider r2q change.\n", cl->classid); + cl->un.leaf.quantum = 200000; + } + if (hopt->quantum) +--- src/linux/linux/include/net/pkt_cls.h 2003-07-04 01:12:28.000000000 -0700 ++++ src/linux/linux.2.4.26/include/net/pkt_cls.h 2004-05-10 22:21:40.000000000 -0700 +@@ -77,7 +77,11 @@ + return -1; + } + +- ++static inline void tcf_destroy(struct tcf_proto *tp) ++{ ++ tp->ops->destroy(tp); ++ kfree(tp); ++} + + extern int register_tcf_proto_ops(struct tcf_proto_ops *ops); + extern int unregister_tcf_proto_ops(struct tcf_proto_ops *ops); diff --git a/obsolete-buildroot/sources/openwrt/kernel/patches/120-openwrt.patch b/obsolete-buildroot/sources/openwrt/kernel/patches/120-openwrt.patch new file mode 100644 index 0000000000..37c1dd34fd --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/kernel/patches/120-openwrt.patch @@ -0,0 +1,2521 @@ +diff -Nurb src/linux/linux.orig/Makefile src/linux/linux/Makefile +--- src/linux/linux.orig/Makefile 2003-10-14 04:00:10.000000000 -0400 ++++ src/linux/linux/Makefile 2004-05-25 21:12:24.000000000 -0400 +@@ -17,7 +17,7 @@ + FINDHPATH = $(HPATH)/asm $(HPATH)/linux $(HPATH)/scsi $(HPATH)/net $(HPATH)/math-emu + + HOSTCC = gcc +-HOSTCFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer ++HOSTCFLAGS = -Wall -Wstrict-prototypes -Os -fomit-frame-pointer + + CROSS_COMPILE = + +@@ -88,7 +88,7 @@ + + CPPFLAGS := -D__KERNEL__ -I$(HPATH) + +-CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -O2 \ ++CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -Wno-trigraphs -Os \ + -fno-strict-aliasing -fno-common + + # Turn on -pg to instrument the kernel with calls to mcount(). +diff -Nurb src/linux/linux.orig/arch/mips/brcm-boards/bcm947xx/setup.c src/linux/linux/arch/mips/brcm-boards/bcm947xx/setup.c +--- src/linux/linux.orig/arch/mips/brcm-boards/bcm947xx/setup.c 2003-11-11 09:08:46.000000000 -0500 ++++ src/linux/linux/arch/mips/brcm-boards/bcm947xx/setup.c 2004-05-25 21:12:24.000000000 -0400 +@@ -27,6 +27,7 @@ + #include + #include + #include ++#include + #endif + + #include +@@ -160,37 +161,38 @@ + #ifdef CONFIG_MTD_PARTITIONS + + static struct mtd_partition bcm947xx_parts[] = { +- { name: "pmon", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ }, ++ { name: "pmon", offset: 0, size: 0, mask_flags: MTD_WRITEABLE, }, + { name: "linux", offset: 0, size: 0, }, + { name: "rootfs", offset: 0, size: 0, /*mask_flags: MTD_WRITEABLE,*/ }, + { name: "nvram", offset: 0, size: 0, }, ++ { name: "OpenWrt", offset: 0, size: 0, }, + { name: NULL, }, + }; + +-struct mtd_partition * __init +-init_mtd_partitions(struct mtd_info *mtd, size_t size) ++ ++static int __init ++find_root(struct mtd_info *mtd, size_t size, struct mtd_partition *part) + { +- struct minix_super_block *minixsb; +- struct ext2_super_block *ext2sb; +- struct romfs_super_block *romfsb; + struct cramfs_super *cramfsb; ++ struct squashfs_super_block *squashfsb; + struct trx_header *trx; ++ + unsigned char buf[512]; + int off; + size_t len; + +- minixsb = (struct minix_super_block *) buf; +- ext2sb = (struct ext2_super_block *) buf; +- romfsb = (struct romfs_super_block *) buf; + cramfsb = (struct cramfs_super *) buf; ++ squashfsb = (struct squashfs_super_block *) buf; + trx = (struct trx_header *) buf; + +- /* Look at every 64 KB boundary */ +- for (off = 0; off < size; off += (64 * 1024)) { ++ part->offset = 0; ++ part->size = 0; ++ ++ for (off = 0; off < size; off += mtd->erasesize) { + memset(buf, 0xe5, sizeof(buf)); + + /* +- * Read block 0 to test for romfs and cramfs superblock ++ * Read block 0 to test for cramfs superblock + */ + if (MTD_READ(mtd, off, sizeof(buf), &len, buf) || + len != sizeof(buf)) +@@ -198,75 +200,105 @@ + + /* Try looking at TRX header for rootfs offset */ + if (le32_to_cpu(trx->magic) == TRX_MAGIC) { +- bcm947xx_parts[1].offset = off; + if (le32_to_cpu(trx->offsets[1]) > off) + off = le32_to_cpu(trx->offsets[1]); + continue; + } + +- /* romfs is at block zero too */ +- if (romfsb->word0 == ROMSB_WORD0 && +- romfsb->word1 == ROMSB_WORD1) { +- printk(KERN_NOTICE +- "%s: romfs filesystem found at block %d\n", +- mtd->name, off / BLOCK_SIZE); +- goto done; +- } +- +- /* so is cramfs */ ++ /* need to find cramfs */ + if (cramfsb->magic == CRAMFS_MAGIC) { + printk(KERN_NOTICE + "%s: cramfs filesystem found at block %d\n", + mtd->name, off / BLOCK_SIZE); +- goto done; +- } + +- /* +- * Read block 1 to test for minix and ext2 superblock +- */ +- if (MTD_READ(mtd, off + BLOCK_SIZE, sizeof(buf), &len, buf) || +- len != sizeof(buf)) +- continue; +- +- /* Try minix */ +- if (minixsb->s_magic == MINIX_SUPER_MAGIC || +- minixsb->s_magic == MINIX_SUPER_MAGIC2) { +- printk(KERN_NOTICE +- "%s: Minix filesystem found at block %d\n", +- mtd->name, off / BLOCK_SIZE); ++ part->size = cramfsb->size; + goto done; + } + +- /* Try ext2 */ +- if (ext2sb->s_magic == cpu_to_le16(EXT2_SUPER_MAGIC)) { ++ /* or squashfs */ ++ if (squashfsb->s_magic == SQUASHFS_MAGIC) { + printk(KERN_NOTICE +- "%s: ext2 filesystem found at block %d\n", ++ "%s: squashfs filesystem found at block %d\n", + mtd->name, off / BLOCK_SIZE); ++ part->size = squashfsb->bytes_used+2048; + goto done; + } +- } + ++ } + printk(KERN_NOTICE +- "%s: Couldn't find valid ROM disk image\n", ++ "%s: Couldn't find valid cramfs image\n", + mtd->name); ++ return -1; ++ ++done: ++ part->offset = off; ++ return 0; ++} ++ ++ ++struct mtd_partition * __init ++init_mtd_partitions(struct mtd_info *mtd, size_t size) ++{ ++ ++ bcm947xx_parts[0].offset=0; ++ bcm947xx_parts[0].size=256*1024; + +- done: + /* Find and size nvram */ + bcm947xx_parts[3].offset = size - ROUNDUP(NVRAM_SPACE, mtd->erasesize); + bcm947xx_parts[3].size = size - bcm947xx_parts[3].offset; + + /* Find and size rootfs */ +- if (off < size) { +- bcm947xx_parts[2].offset = off; +- bcm947xx_parts[2].size = bcm947xx_parts[3].offset - bcm947xx_parts[2].offset; +- } ++ //if (off < size) { ++ // bcm947xx_parts[2].offset = off; ++ // bcm947xx_parts[2].size = bcm947xx_parts[3].offset - bcm947xx_parts[2].offset; ++ //} ++ ++ /* Find and size rootfs */ ++ find_root(mtd,size,&bcm947xx_parts[2]); ++ ++ + + /* Size linux (kernel and rootfs) */ ++ bcm947xx_parts[1].offset = bcm947xx_parts[0].size; + bcm947xx_parts[1].size = bcm947xx_parts[3].offset - bcm947xx_parts[1].offset; + ++ ++ ++ /* calculate leftover flash, and assign it to the jffs partition */ ++ size_t spot; ++ size_t len; ++ size_t mask; ++ // get the offset to the end of the root_fs ++ spot=bcm947xx_parts[2].offset+bcm947xx_parts[2].size; ++ // round it up to an erase size boundary ++ spot+=mtd->erasesize-1; ++ // mask the number to the boundary ++ mask=mtd->erasesize; ++ mask=mask-1; ++ mask=mask^0xffffffff; ++ spot&=mask; ++ // length = flashsize - start position - nvram size ++ len=size-spot; ++ len=len-bcm947xx_parts[3].size; ++ ++ ++ bcm947xx_parts[4].offset = spot; ++ bcm947xx_parts[4].size = len; ++ ++ ++ ++ + /* Size pmon */ + bcm947xx_parts[0].size = bcm947xx_parts[1].offset - bcm947xx_parts[0].offset; + ++ //int x; ++ //for(x=0; x<5; x++) { ++ // printk(KERN_NOTICE ++ // "Partition %d mask_flags %08x\n", ++ // x,bcm947xx_parts[x].mask_flags); ++ //} ++ ++ + return bcm947xx_parts; + } + +diff -Nurb src/linux/linux.orig/drivers/mtd/maps/bcm947xx-flash.c src/linux/linux/drivers/mtd/maps/bcm947xx-flash.c +--- src/linux/linux.orig/drivers/mtd/maps/bcm947xx-flash.c 2003-11-08 04:35:52.000000000 -0500 ++++ src/linux/linux/drivers/mtd/maps/bcm947xx-flash.c 2004-05-25 21:12:24.000000000 -0400 +@@ -82,7 +82,21 @@ + + void bcm947xx_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) + { ++ //memcpy_fromio(to, map->map_priv_1 + from, len); ++ if (len==1) { + memcpy_fromio(to, map->map_priv_1 + from, len); ++ } else { ++ int i; ++ u16 *dest = (u16 *) to; ++ u16 *src = (u16 *) (map->map_priv_1 + from); ++ ++ for (i = 0; i < (len / 2); i++) { ++ dest[i] = src[i]; ++ } ++ ++ if (len & 1) ++ *((u8 *)dest+len-1) = src[i] & 0xff; ++ } + } + + void bcm947xx_map_write8(struct map_info *map, __u8 d, unsigned long adr) +diff -Nurb src/linux/linux.orig/drivers/net/Makefile src/linux/linux/drivers/net/Makefile +--- src/linux/linux.orig/drivers/net/Makefile 2004-02-12 21:35:15.000000000 -0500 ++++ src/linux/linux/drivers/net/Makefile 2004-05-25 21:12:24.000000000 -0400 +@@ -25,7 +25,7 @@ + list-multi := rcpci.o + rcpci-objs := rcpci45.o rclanmtl.o + +-subdir-m += mac ++# subdir-m += mac + subdir-m += diag + + ifeq ($(CONFIG_HW_QOS),y) +diff -Nurb src/linux/linux.orig/fs/Config.in src/linux/linux/fs/Config.in +--- src/linux/linux.orig/fs/Config.in 2003-07-04 04:12:05.000000000 -0400 ++++ src/linux/linux/fs/Config.in 2004-05-25 21:13:03.000000000 -0400 +@@ -47,6 +47,7 @@ + int 'JFFS2 debugging verbosity (0 = quiet, 2 = noisy)' CONFIG_JFFS2_FS_DEBUG 0 + fi + tristate 'Compressed ROM file system support' CONFIG_CRAMFS ++tristate 'Squashed file system support' CONFIG_SQUASHFS + bool 'Virtual memory file system support (former shm fs)' CONFIG_TMPFS + define_bool CONFIG_RAMFS y + +diff -Nurb src/linux/linux.orig/fs/Makefile src/linux/linux/fs/Makefile +--- src/linux/linux.orig/fs/Makefile 2003-07-04 04:12:05.000000000 -0400 ++++ src/linux/linux/fs/Makefile 2004-05-25 21:13:03.000000000 -0400 +@@ -68,6 +68,7 @@ + subdir-$(CONFIG_SUN_OPENPROMFS) += openpromfs + subdir-$(CONFIG_BEFS_FS) += befs + subdir-$(CONFIG_JFS_FS) += jfs ++subdir-$(CONFIG_SQUASHFS) += squashfs + + + obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o +diff -Nurb src/linux/linux.orig/fs/squashfs/Makefile src/linux/linux/fs/squashfs/Makefile +--- src/linux/linux.orig/fs/squashfs/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/fs/squashfs/Makefile 2004-05-25 21:13:03.000000000 -0400 +@@ -0,0 +1,11 @@ ++# ++# Makefile for the linux squashfs routines. ++# ++ ++O_TARGET := squashfs.o ++ ++obj-y := inode.o ++ ++obj-m := $(O_TARGET) ++ ++include $(TOPDIR)/Rules.make +diff -Nurb src/linux/linux.orig/fs/squashfs/inode.c src/linux/linux/fs/squashfs/inode.c +--- src/linux/linux.orig/fs/squashfs/inode.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/fs/squashfs/inode.c 2004-05-25 21:13:03.000000000 -0400 +@@ -0,0 +1,1515 @@ ++/* ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * Copyright (c) 2002, 2003, 2004 Phillip Lougher ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2, ++ * or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * Squashfs - a compressed read only filesystem for Linux ++ * ++ * inode.c ++ */ ++ ++#define SQUASHFS_1_0_COMPATIBILITY ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef SQUASHFS_TRACE ++#define TRACE(s, args...) printk(KERN_NOTICE "SQUASHFS: "s, ## args) ++#else ++#define TRACE(s, args...) {} ++#endif ++ ++#define ERROR(s, args...) printk(KERN_ERR "SQUASHFS error: "s, ## args) ++ ++#define SERROR(s, args...) if(!silent) printk(KERN_ERR "SQUASHFS error: "s, ## args) ++#define WARNING(s, args...) printk(KERN_WARNING "SQUASHFS: "s, ## args) ++ ++static struct super_block *squashfs_read_super(struct super_block *, void *, int); ++static void squashfs_put_super(struct super_block *); ++static int squashfs_statfs(struct super_block *, struct statfs *); ++static int squashfs_symlink_readpage(struct file *file, struct page *page); ++static int squashfs_readpage(struct file *file, struct page *page); ++static int squashfs_readpage4K(struct file *file, struct page *page); ++static int squashfs_readdir(struct file *, void *, filldir_t); ++static struct dentry *squashfs_lookup(struct inode *, struct dentry *); ++static unsigned int read_data(struct super_block *s, char *buffer, ++ unsigned int index, unsigned int length, int, unsigned int *next_index); ++static int squashfs_get_cached_block(struct super_block *s, char *buffer, ++ unsigned int block, unsigned int offset, int length, ++ unsigned int *next_block, unsigned int *next_offset); ++static struct inode *squashfs_iget(struct super_block *s, squashfs_inode inode); ++static unsigned int read_blocklist(struct inode *inode, int index, int readahead_blks, ++ char *block_list, char **block_p, unsigned int *bsize); ++static void squashfs_put_super(struct super_block *s); ++ ++#ifdef SQUASHFS_1_0_COMPATIBILITY ++static int squashfs_readpage_lessthan4K(struct file *file, struct page *page); ++static struct inode *squashfs_iget_1(struct super_block *s, squashfs_inode inode); ++static unsigned int read_blocklist_1(struct inode *inode, int index, int readahead_blks, ++ char *block_list, char **block_p, unsigned int *bsize); ++#endif ++ ++DECLARE_MUTEX(read_data_mutex); ++ ++static z_stream stream; ++ ++static DECLARE_FSTYPE_DEV(squashfs_fs_type, "squashfs", squashfs_read_super); ++ ++static unsigned char squashfs_filetype_table[] = { ++ DT_UNKNOWN, DT_DIR, DT_REG, DT_LNK, DT_BLK, DT_CHR, DT_FIFO, DT_SOCK ++}; ++ ++static struct super_operations squashfs_ops = { ++ statfs: squashfs_statfs, ++ put_super: squashfs_put_super, ++}; ++ ++static struct address_space_operations squashfs_symlink_aops = { ++ readpage: squashfs_symlink_readpage ++}; ++ ++static struct address_space_operations squashfs_aops = { ++ readpage: squashfs_readpage ++}; ++ ++static struct address_space_operations squashfs_aops_4K = { ++ readpage: squashfs_readpage4K ++}; ++ ++#ifdef SQUASHFS_1_0_COMPATIBILITY ++static struct address_space_operations squashfs_aops_lessthan4K = { ++ readpage: squashfs_readpage_lessthan4K ++}; ++#endif ++ ++static struct file_operations squashfs_dir_ops = { ++ read: generic_read_dir, ++ readdir: squashfs_readdir ++}; ++ ++static struct inode_operations squashfs_dir_inode_ops = { ++ lookup: squashfs_lookup ++}; ++ ++ ++static unsigned int read_data(struct super_block *s, char *buffer, ++ unsigned int index, unsigned int length, int datablock, unsigned int *next_index) ++{ ++ squashfs_sb_info *msBlk = &s->u.squashfs_sb; ++ struct buffer_head *bh[((SQUASHFS_FILE_MAX_SIZE - 1) >> msBlk->devblksize_log2) + 2]; ++ unsigned int offset = index & ((1 << msBlk->devblksize_log2) - 1); ++ unsigned int cur_index = index >> msBlk->devblksize_log2; ++ int bytes, avail_bytes, b, k; ++ char *c_buffer; ++ unsigned int compressed; ++ unsigned int c_byte = length; ++ ++ if(c_byte) { ++ bytes = msBlk->devblksize - offset; ++ if(datablock) { ++ c_buffer = (compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte)) ? msBlk->read_data : buffer; ++ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); ++ } else { ++ c_buffer = (compressed = SQUASHFS_COMPRESSED(c_byte)) ? msBlk->read_data : buffer; ++ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); ++ } ++ ++ TRACE("Block @ 0x%x, %scompressed size %d\n", index, compressed ? "" : "un", (unsigned int) c_byte); ++ ++ if(!(bh[0] = sb_getblk(s, cur_index))) ++ goto block_release; ++ for(b = 1; bytes < c_byte; b++) { ++ if(!(bh[b] = sb_getblk(s, ++cur_index))) ++ goto block_release; ++ bytes += msBlk->devblksize; ++ } ++ ll_rw_block(READ, b, bh); ++ } else { ++ unsigned short temp; ++ if(!(bh[0] = sb_bread(s, cur_index))) ++ goto read_failure; ++ ++ if(msBlk->devblksize - offset == 1) { ++ if(msBlk->swap) ++ ((unsigned char *) &temp)[1] = *((unsigned char *) (bh[0]->b_data + offset)); ++ else ++ ((unsigned char *) &temp)[0] = *((unsigned char *) (bh[0]->b_data + offset)); ++ brelse(bh[0]); ++ if(!(bh[0] = sb_bread(s, ++cur_index))) ++ goto read_failure; ++ if(msBlk->swap) ++ ((unsigned char *) &temp)[0] = *((unsigned char *) bh[0]->b_data); ++ else ++ ((unsigned char *) &temp)[1] = *((unsigned char *) bh[0]->b_data); ++ c_byte = temp; ++ offset = 1; ++ } ++ else { ++ if(msBlk->swap) { ++ unsigned short temp; ++ ((unsigned char *) &temp)[1] = *((unsigned char *) (bh[0]->b_data + offset)); ++ ((unsigned char *) &temp)[0] = *((unsigned char *) (bh[0]->b_data + offset + 1)); ++ c_byte = temp; ++ } else ++ c_byte = *((unsigned short *) (bh[0]->b_data + offset)); ++ offset += 2; ++ } ++ if(SQUASHFS_CHECK_DATA(msBlk->sBlk.flags)) { ++ if(offset == msBlk->devblksize) { ++ brelse(bh[0]); ++ if(!(bh[0] = sb_bread(s, ++cur_index))) ++ goto read_failure; ++ offset = 0; ++ } ++ if(*((unsigned char *) (bh[0]->b_data + offset)) != SQUASHFS_MARKER_BYTE) { ++ ERROR("Metadata block marker corrupt @ %x\n", index); ++ brelse(bh[0]); ++ return 0; ++ } ++ offset ++; ++ } ++ ++ bytes = msBlk->devblksize - offset; ++ if(datablock) { ++ c_buffer = (compressed = SQUASHFS_COMPRESSED_BLOCK(c_byte)) ? msBlk->read_data : buffer; ++ c_byte = SQUASHFS_COMPRESSED_SIZE_BLOCK(c_byte); ++ } else { ++ c_buffer = (compressed = SQUASHFS_COMPRESSED(c_byte)) ? msBlk->read_data : buffer; ++ c_byte = SQUASHFS_COMPRESSED_SIZE(c_byte); ++ } ++ ++ TRACE("Block @ 0x%x, %scompressed size %d\n", index, compressed ? "" : "un", (unsigned int) c_byte); ++ ++ for(b = 1; bytes < c_byte; b++) { ++ if(!(bh[b] = sb_getblk(s, ++cur_index))) ++ goto block_release; ++ bytes += msBlk->devblksize; ++ } ++ ll_rw_block(READ, b - 1, bh + 1); ++ } ++ ++ if(compressed) ++ down(&read_data_mutex); ++ ++ for(bytes = 0, k = 0; k < b; k++) { ++ avail_bytes = (c_byte - bytes) > (msBlk->devblksize - offset) ? msBlk->devblksize - offset : c_byte - bytes; ++ wait_on_buffer(bh[k]); ++ memcpy(c_buffer + bytes, bh[k]->b_data + offset, avail_bytes); ++ bytes += avail_bytes; ++ offset = 0; ++ brelse(bh[k]); ++ } ++ ++ /* ++ * uncompress block ++ */ ++ if(compressed) { ++ int zlib_err; ++ ++ stream.next_in = c_buffer; ++ stream.avail_in = c_byte; ++ stream.next_out = buffer; ++ stream.avail_out = msBlk->read_size; ++ if(((zlib_err = zlib_inflateInit(&stream)) != Z_OK) || ++ ((zlib_err = zlib_inflate(&stream, Z_FINISH)) != Z_STREAM_END) || ++ ((zlib_err = zlib_inflateEnd(&stream)) != Z_OK)) { ++ ERROR("zlib_fs returned unexpected result 0x%x\n", zlib_err); ++ bytes = 0; ++ } else ++ bytes = stream.total_out; ++ up(&read_data_mutex); ++ } ++ ++ if(next_index) ++ *next_index = index + c_byte + (length ? 0 : (SQUASHFS_CHECK_DATA(msBlk->sBlk.flags) ? 3 : 2)); ++ ++ return bytes; ++ ++block_release: ++ while(--b >= 0) brelse(bh[b]); ++ ++read_failure: ++ ERROR("sb_bread failed reading block 0x%x\n", cur_index); ++ return 0; ++} ++ ++ ++static int squashfs_get_cached_block(struct super_block *s, char *buffer, ++ unsigned int block, unsigned int offset, int length, ++ unsigned int *next_block, unsigned int *next_offset) ++{ ++ squashfs_sb_info *msBlk = &s->u.squashfs_sb; ++ int n, i, bytes, return_length = length; ++ unsigned int next_index; ++ ++ TRACE("Entered squashfs_get_cached_block [%x:%x]\n", block, offset); ++ ++ for(;;) { ++ for(i = 0; i < SQUASHFS_CACHED_BLKS; i++) ++ if(msBlk->block_cache[i].block == block) ++ break; ++ ++ down(&msBlk->block_cache_mutex); ++ if(i == SQUASHFS_CACHED_BLKS) { ++ /* read inode header block */ ++ for(i = msBlk->next_cache, n = SQUASHFS_CACHED_BLKS; n ; n --, i = (i + 1) % SQUASHFS_CACHED_BLKS) ++ if(msBlk->block_cache[i].block != SQUASHFS_USED_BLK) ++ break; ++ if(n == 0) { ++ up(&msBlk->block_cache_mutex); ++ sleep_on(&msBlk->waitq); ++ continue; ++ } ++ msBlk->next_cache = (i + 1) % SQUASHFS_CACHED_BLKS; ++ ++ if(msBlk->block_cache[i].block == SQUASHFS_INVALID_BLK) { ++ if(!(msBlk->block_cache[i].data = (unsigned char *) ++ kmalloc(SQUASHFS_METADATA_SIZE, GFP_KERNEL))) { ++ ERROR("Failed to allocate cache block\n"); ++ up(&msBlk->block_cache_mutex); ++ return 0; ++ } ++ } ++ ++ msBlk->block_cache[i].block = SQUASHFS_USED_BLK; ++ up(&msBlk->block_cache_mutex); ++ if(!(msBlk->block_cache[i].length = read_data(s, msBlk->block_cache[i].data, block, 0, 0, ++ &next_index))) { ++ ERROR("Unable to read cache block [%x:%x]\n", block, offset); ++ return 0; ++ } ++ down(&msBlk->block_cache_mutex); ++ wake_up(&msBlk->waitq); ++ msBlk->block_cache[i].block = block; ++ msBlk->block_cache[i].next_index = next_index; ++ TRACE("Read cache block [%x:%x]\n", block, offset); ++ } ++ ++ if(msBlk->block_cache[i].block != block) { ++ up(&msBlk->block_cache_mutex); ++ continue; ++ } ++ ++ if((bytes = msBlk->block_cache[i].length - offset) >= length) { ++ if(buffer) ++ memcpy(buffer, msBlk->block_cache[i].data + offset, length); ++ if(msBlk->block_cache[i].length - offset == length) { ++ *next_block = msBlk->block_cache[i].next_index; ++ *next_offset = 0; ++ } else { ++ *next_block = block; ++ *next_offset = offset + length; ++ } ++ ++ up(&msBlk->block_cache_mutex); ++ return return_length; ++ } else { ++ if(buffer) { ++ memcpy(buffer, msBlk->block_cache[i].data + offset, bytes); ++ buffer += bytes; ++ } ++ block = msBlk->block_cache[i].next_index; ++ up(&msBlk->block_cache_mutex); ++ length -= bytes; ++ offset = 0; ++ } ++ } ++} ++ ++ ++static int get_fragment_location(struct super_block *s, unsigned int fragment, unsigned int *fragment_start_block, unsigned int *fragment_size) ++{ ++ squashfs_sb_info *msBlk = &s->u.squashfs_sb; ++ unsigned int start_block = msBlk->fragment_index[SQUASHFS_FRAGMENT_INDEX(fragment)]; ++ int offset = SQUASHFS_FRAGMENT_INDEX_OFFSET(fragment); ++ squashfs_fragment_entry fragment_entry; ++ ++ if(msBlk->swap) { ++ squashfs_fragment_entry sfragment_entry; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sfragment_entry, start_block, offset, ++ sizeof(sfragment_entry), &start_block, &offset)) ++ return 0; ++ SQUASHFS_SWAP_FRAGMENT_ENTRY(&fragment_entry, &sfragment_entry); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &fragment_entry, start_block, offset, ++ sizeof(fragment_entry), &start_block, &offset)) ++ return 0; ++ ++ *fragment_start_block = fragment_entry.start_block; ++ *fragment_size = fragment_entry.size; ++ ++ return 1; ++} ++ ++ ++void release_cached_fragment(squashfs_sb_info *msBlk, struct squashfs_fragment_cache *fragment) ++{ ++ down(&msBlk->fragment_mutex); ++ fragment->locked --; ++ wake_up(&msBlk->fragment_wait_queue); ++ up(&msBlk->fragment_mutex); ++} ++ ++ ++struct squashfs_fragment_cache *get_cached_fragment(struct super_block *s, unsigned int start_block, int length) ++{ ++ int i, n; ++ squashfs_sb_info *msBlk = &s->u.squashfs_sb; ++ ++ for(;;) { ++ down(&msBlk->fragment_mutex); ++ for(i = 0; i < SQUASHFS_CACHED_FRAGMENTS && msBlk->fragment[i].block != start_block; i++); ++ if(i == SQUASHFS_CACHED_FRAGMENTS) { ++ for(i = msBlk->next_fragment, n = SQUASHFS_CACHED_FRAGMENTS; ++ n && msBlk->fragment[i].locked; n--, i = (i + 1) % SQUASHFS_CACHED_FRAGMENTS); ++ ++ if(n == 0) { ++ up(&msBlk->fragment_mutex); ++ sleep_on(&msBlk->fragment_wait_queue); ++ continue; ++ } ++ msBlk->next_fragment = (msBlk->next_fragment + 1) % SQUASHFS_CACHED_FRAGMENTS; ++ ++ if(msBlk->fragment[i].data == NULL) ++ if(!(msBlk->fragment[i].data = (unsigned char *) ++ kmalloc(SQUASHFS_FILE_MAX_SIZE, GFP_KERNEL))) { ++ ERROR("Failed to allocate fragment cache block\n"); ++ up(&msBlk->fragment_mutex); ++ return NULL; ++ } ++ ++ msBlk->fragment[i].block = SQUASHFS_INVALID_BLK; ++ msBlk->fragment[i].locked = 1; ++ up(&msBlk->fragment_mutex); ++ if(!(msBlk->fragment[i].length = read_data(s, msBlk->fragment[i].data, start_block, length, ++ 1, NULL))) { ++ ERROR("Unable to read fragment cache block [%x]\n", start_block); ++ msBlk->fragment[i].locked = 0; ++ return NULL; ++ } ++ msBlk->fragment[i].block = start_block; ++ TRACE("New fragment %d, start block %d, locked %d\n", i, msBlk->fragment[i].block, msBlk->fragment[i].locked); ++ return &msBlk->fragment[i]; ++ } ++ ++ msBlk->fragment[i].locked ++; ++ up(&msBlk->fragment_mutex); ++ ++ TRACE("Got fragment %d, start block %d, locked %d\n", i, msBlk->fragment[i].block, msBlk->fragment[i].locked); ++ return &msBlk->fragment[i]; ++ } ++} ++ ++ ++#ifdef SQUASHFS_1_0_COMPATIBILITY ++static struct inode *squashfs_iget_1(struct super_block *s, squashfs_inode inode) ++{ ++ struct inode *i = new_inode(s); ++ squashfs_sb_info *msBlk = &s->u.squashfs_sb; ++ squashfs_super_block *sBlk = &msBlk->sBlk; ++ unsigned int block = SQUASHFS_INODE_BLK(inode) + sBlk->inode_table_start; ++ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); ++ unsigned int next_block, next_offset; ++ squashfs_base_inode_header_1 inodeb; ++ ++ TRACE("Entered squashfs_iget_1\n"); ++ ++ if(msBlk->swap) { ++ squashfs_base_inode_header_1 sinodeb; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodeb, block, offset, ++ sizeof(sinodeb), &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_BASE_INODE_HEADER_1(&inodeb, &sinodeb, sizeof(sinodeb)); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodeb, block, offset, ++ sizeof(inodeb), &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = 1; ++ ++ i->i_mtime = sBlk->mkfs_time; ++ i->i_atime = sBlk->mkfs_time; ++ i->i_ctime = sBlk->mkfs_time; ++ ++ if(inodeb.inode_type != SQUASHFS_IPC_TYPE) ++ i->i_uid = msBlk->uid[((inodeb.inode_type - 1) / SQUASHFS_TYPES) * 16 + inodeb.uid]; ++ i->i_ino = SQUASHFS_MK_VFS_INODE(block - sBlk->inode_table_start, offset); ++ ++ i->i_mode = inodeb.mode; ++ ++ switch(inodeb.inode_type == SQUASHFS_IPC_TYPE ? SQUASHFS_IPC_TYPE : (inodeb.inode_type - 1) % SQUASHFS_TYPES + 1) { ++ case SQUASHFS_FILE_TYPE: { ++ squashfs_reg_inode_header_1 inodep; ++ ++ if(msBlk->swap) { ++ squashfs_reg_inode_header_1 sinodep; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_REG_INODE_HEADER_1(&inodep, &sinodep); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep.file_size; ++ i->i_fop = &generic_ro_fops; ++ if(sBlk->block_size > 4096) ++ i->i_data.a_ops = &squashfs_aops; ++ else if(sBlk->block_size == 4096) ++ i->i_data.a_ops = &squashfs_aops_4K; ++ else ++ i->i_data.a_ops = &squashfs_aops_lessthan4K; ++ i->i_mode |= S_IFREG; ++ i->i_mtime = inodep.mtime; ++ i->i_atime = inodep.mtime; ++ i->i_ctime = inodep.mtime; ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1; ++ i->i_blksize = PAGE_CACHE_SIZE; ++ i->u.squashfs_i.fragment_start_block = SQUASHFS_INVALID_BLK; ++ i->u.squashfs_i.fragment_offset = 0; ++ i->u.squashfs_i.start_block = inodep.start_block; ++ i->u.squashfs_i.block_list_start = next_block; ++ i->u.squashfs_i.offset = next_offset; ++ TRACE("File inode %x:%x, start_block %x, block_list_start %x, offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, inodep.start_block, next_block, next_offset); ++ break; ++ } ++ case SQUASHFS_DIR_TYPE: { ++ squashfs_dir_inode_header_1 inodep; ++ ++ if(msBlk->swap) { ++ squashfs_dir_inode_header_1 sinodep; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DIR_INODE_HEADER_1(&inodep, &sinodep); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep.file_size; ++ i->i_op = &squashfs_dir_inode_ops; ++ i->i_fop = &squashfs_dir_ops; ++ i->i_mode |= S_IFDIR; ++ i->i_mtime = inodep.mtime; ++ i->i_atime = inodep.mtime; ++ i->i_ctime = inodep.mtime; ++ i->u.squashfs_i.start_block = inodep.start_block; ++ i->u.squashfs_i.offset = inodep.offset; ++ TRACE("Directory inode %x:%x, start_block %x, offset %x\n", SQUASHFS_INODE_BLK(inode), offset, ++ inodep.start_block, inodep.offset); ++ break; ++ } ++ case SQUASHFS_SYMLINK_TYPE: { ++ squashfs_symlink_inode_header_1 inodep; ++ ++ if(msBlk->swap) { ++ squashfs_symlink_inode_header_1 sinodep; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(&inodep, &sinodep); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep.symlink_size; ++ i->i_op = &page_symlink_inode_operations; ++ i->i_data.a_ops = &squashfs_symlink_aops; ++ i->i_mode |= S_IFLNK; ++ i->u.squashfs_i.start_block = next_block; ++ i->u.squashfs_i.offset = next_offset; ++ TRACE("Symbolic link inode %x:%x, start_block %x, offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, next_block, next_offset); ++ break; ++ } ++ case SQUASHFS_BLKDEV_TYPE: ++ case SQUASHFS_CHRDEV_TYPE: { ++ squashfs_dev_inode_header_1 inodep; ++ ++ if(msBlk->swap) { ++ squashfs_dev_inode_header_1 sinodep; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DEV_INODE_HEADER_1(&inodep, &sinodep); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->i_size = 0; ++ i->i_mode |= (inodeb.inode_type == SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : S_IFBLK; ++ init_special_inode(i, i->i_mode, inodep.rdev); ++ TRACE("Device inode %x:%x, rdev %x\n", SQUASHFS_INODE_BLK(inode), offset, inodep.rdev); ++ break; ++ } ++ case SQUASHFS_IPC_TYPE: { ++ squashfs_ipc_inode_header_1 inodep; ++ ++ if(msBlk->swap) { ++ squashfs_ipc_inode_header_1 sinodep; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_IPC_INODE_HEADER_1(&inodep, &sinodep); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->i_size = 0; ++ i->i_mode |= (inodep.type == SQUASHFS_FIFO_TYPE) ? S_IFIFO : S_IFSOCK; ++ i->i_uid = msBlk->uid[inodep.offset * 16 + inodeb.uid]; ++ init_special_inode(i, i->i_mode, 0); ++ break; ++ } ++ default: ++ ERROR("Unknown inode type %d in squashfs_iget!\n", inodeb.inode_type); ++ goto failed_read1; ++ } ++ ++ if(inodeb.guid == SQUASHFS_GUIDS) ++ i->i_gid = i->i_uid; ++ else ++ i->i_gid = msBlk->guid[inodeb.guid]; ++ ++ return i; ++ ++failed_read: ++ ERROR("Unable to read inode [%x:%x]\n", block, offset); ++ ++failed_read1: ++ return NULL; ++} ++#endif ++ ++ ++static struct inode *squashfs_iget(struct super_block *s, squashfs_inode inode) ++{ ++ struct inode *i = new_inode(s); ++ squashfs_sb_info *msBlk = &s->u.squashfs_sb; ++ squashfs_super_block *sBlk = &msBlk->sBlk; ++ unsigned int block = SQUASHFS_INODE_BLK(inode) + sBlk->inode_table_start; ++ unsigned int offset = SQUASHFS_INODE_OFFSET(inode); ++ unsigned int next_block, next_offset; ++ squashfs_base_inode_header inodeb; ++ ++ TRACE("Entered squashfs_iget\n"); ++ ++ if(msBlk->swap) { ++ squashfs_base_inode_header sinodeb; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodeb, block, offset, ++ sizeof(sinodeb), &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_BASE_INODE_HEADER(&inodeb, &sinodeb, sizeof(sinodeb)); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodeb, block, offset, ++ sizeof(inodeb), &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->i_nlink = 1; ++ ++ i->i_mtime = sBlk->mkfs_time; ++ i->i_atime = sBlk->mkfs_time; ++ i->i_ctime = sBlk->mkfs_time; ++ ++ if(inodeb.inode_type != SQUASHFS_IPC_TYPE) ++ i->i_uid = msBlk->uid[((inodeb.inode_type - 1) / SQUASHFS_TYPES) * 16 + inodeb.uid]; ++ i->i_ino = SQUASHFS_MK_VFS_INODE(block - sBlk->inode_table_start, offset); ++ ++ i->i_mode = inodeb.mode; ++ ++ switch(inodeb.inode_type) { ++ case SQUASHFS_FILE_TYPE: { ++ squashfs_reg_inode_header inodep; ++ ++ if(msBlk->swap) { ++ squashfs_reg_inode_header sinodep; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_REG_INODE_HEADER(&inodep, &sinodep); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->u.squashfs_i.fragment_start_block = SQUASHFS_INVALID_BLK; ++ if(inodep.fragment != SQUASHFS_INVALID_BLK && !get_fragment_location(s, inodep.fragment, ++ &i->u.squashfs_i.fragment_start_block, &i->u.squashfs_i.fragment_size)) ++ goto failed_read; ++ ++ i->u.squashfs_i.fragment_offset = inodep.offset; ++ i->i_size = inodep.file_size; ++ i->i_fop = &generic_ro_fops; ++ if(sBlk->block_size > 4096) ++ i->i_data.a_ops = &squashfs_aops; ++ else ++ i->i_data.a_ops = &squashfs_aops_4K; ++ i->i_mode |= S_IFREG; ++ i->i_mtime = inodep.mtime; ++ i->i_atime = inodep.mtime; ++ i->i_ctime = inodep.mtime; ++ i->i_blocks = ((i->i_size - 1) >> 9) + 1; ++ i->i_blksize = PAGE_CACHE_SIZE; ++ i->u.squashfs_i.start_block = inodep.start_block; ++ i->u.squashfs_i.block_list_start = next_block; ++ i->u.squashfs_i.offset = next_offset; ++ TRACE("File inode %x:%x, start_block %x, block_list_start %x, offset %x fragment_index %x fragment_offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, inodep.start_block, next_block, next_offset, inodep.fragment, inodep.offset); ++ break; ++ } ++ case SQUASHFS_DIR_TYPE: { ++ squashfs_dir_inode_header inodep; ++ ++ if(msBlk->swap) { ++ squashfs_dir_inode_header sinodep; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DIR_INODE_HEADER(&inodep, &sinodep); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep.file_size; ++ i->i_op = &squashfs_dir_inode_ops; ++ i->i_fop = &squashfs_dir_ops; ++ i->i_mode |= S_IFDIR; ++ i->i_mtime = inodep.mtime; ++ i->i_atime = inodep.mtime; ++ i->i_ctime = inodep.mtime; ++ i->u.squashfs_i.start_block = inodep.start_block; ++ i->u.squashfs_i.offset = inodep.offset; ++ TRACE("Directory inode %x:%x, start_block %x, offset %x\n", SQUASHFS_INODE_BLK(inode), offset, ++ inodep.start_block, inodep.offset); ++ break; ++ } ++ case SQUASHFS_SYMLINK_TYPE: { ++ squashfs_symlink_inode_header inodep; ++ ++ if(msBlk->swap) { ++ squashfs_symlink_inode_header sinodep; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_SYMLINK_INODE_HEADER(&inodep, &sinodep); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->i_size = inodep.symlink_size; ++ i->i_op = &page_symlink_inode_operations; ++ i->i_data.a_ops = &squashfs_symlink_aops; ++ i->i_mode |= S_IFLNK; ++ i->u.squashfs_i.start_block = next_block; ++ i->u.squashfs_i.offset = next_offset; ++ TRACE("Symbolic link inode %x:%x, start_block %x, offset %x\n", ++ SQUASHFS_INODE_BLK(inode), offset, next_block, next_offset); ++ break; ++ } ++ case SQUASHFS_BLKDEV_TYPE: ++ case SQUASHFS_CHRDEV_TYPE: { ++ squashfs_dev_inode_header inodep; ++ ++ if(msBlk->swap) { ++ squashfs_dev_inode_header sinodep; ++ ++ if(!squashfs_get_cached_block(s, (char *) &sinodep, block, offset, sizeof(sinodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ SQUASHFS_SWAP_DEV_INODE_HEADER(&inodep, &sinodep); ++ } else ++ if(!squashfs_get_cached_block(s, (char *) &inodep, block, offset, sizeof(inodep), ++ &next_block, &next_offset)) ++ goto failed_read; ++ ++ i->i_size = 0; ++ i->i_mode |= (inodeb.inode_type == SQUASHFS_CHRDEV_TYPE) ? S_IFCHR : S_IFBLK; ++ init_special_inode(i, i->i_mode, inodep.rdev); ++ TRACE("Device inode %x:%x, rdev %x\n", SQUASHFS_INODE_BLK(inode), offset, inodep.rdev); ++ break; ++ } ++ case SQUASHFS_FIFO_TYPE: ++ case SQUASHFS_SOCKET_TYPE: { ++ i->i_size = 0; ++ i->i_mode |= (inodeb.inode_type == SQUASHFS_FIFO_TYPE) ? S_IFIFO : S_IFSOCK; ++ init_special_inode(i, i->i_mode, 0); ++ break; ++ } ++ default: ++ ERROR("Unknown inode type %d in squashfs_iget!\n", inodeb.inode_type); ++ goto failed_read1; ++ } ++ ++ if(inodeb.guid == SQUASHFS_GUIDS) ++ i->i_gid = i->i_uid; ++ else ++ i->i_gid = msBlk->guid[inodeb.guid]; ++ ++ return i; ++ ++failed_read: ++ ERROR("Unable to read inode [%x:%x]\n", block, offset); ++ ++failed_read1: ++ return NULL; ++} ++ ++ ++static struct super_block *squashfs_read_super(struct super_block *s, ++ void *data, int silent) ++{ ++ kdev_t dev = s->s_dev; ++ squashfs_sb_info *msBlk = &s->u.squashfs_sb; ++ squashfs_super_block *sBlk = &msBlk->sBlk; ++ int i; ++ ++ TRACE("Entered squashfs_read_superblock\n"); ++ ++ msBlk->devblksize = get_hardsect_size(dev); ++ if(msBlk->devblksize < BLOCK_SIZE) ++ msBlk->devblksize = BLOCK_SIZE; ++ msBlk->devblksize_log2 = ffz(~msBlk->devblksize); ++ set_blocksize(dev, msBlk->devblksize); ++ s->s_blocksize = msBlk->devblksize; ++ s->s_blocksize_bits = msBlk->devblksize_log2; ++ ++ init_MUTEX(&msBlk->read_page_mutex); ++ init_MUTEX(&msBlk->block_cache_mutex); ++ init_MUTEX(&msBlk->fragment_mutex); ++ ++ init_waitqueue_head(&msBlk->waitq); ++ init_waitqueue_head(&msBlk->fragment_wait_queue); ++ ++ if(!read_data(s, (char *) sBlk, SQUASHFS_START, sizeof(squashfs_super_block) | SQUASHFS_COMPRESSED_BIT, 0, NULL)) { ++ SERROR("unable to read superblock\n"); ++ goto failed_mount; ++ } ++ ++ /* Check it is a SQUASHFS superblock */ ++ msBlk->swap = 0; ++ if((s->s_magic = sBlk->s_magic) != SQUASHFS_MAGIC) { ++ if(sBlk->s_magic == SQUASHFS_MAGIC_SWAP) { ++ squashfs_super_block sblk; ++ WARNING("Mounting a different endian SQUASHFS filesystem on %s\n", bdevname(dev)); ++ SQUASHFS_SWAP_SUPER_BLOCK(&sblk, sBlk); ++ memcpy(sBlk, &sblk, sizeof(squashfs_super_block)); ++ msBlk->swap = 1; ++ } else { ++ SERROR("Can't find a SQUASHFS superblock on %s\n", bdevname(dev)); ++ goto failed_mount; ++ } ++ } ++ ++ /* Check the MAJOR & MINOR versions */ ++#ifdef SQUASHFS_1_0_COMPATIBILITY ++ if((sBlk->s_major != 1) && (sBlk->s_major != 2 || sBlk->s_minor > SQUASHFS_MINOR)) { ++ SERROR("Major/Minor mismatch, filesystem is (%d:%d), I support (1 : x) or (2 : <= %d)\n", ++ sBlk->s_major, sBlk->s_minor, SQUASHFS_MINOR); ++ goto failed_mount; ++ } ++ if(sBlk->s_major == 1) ++ sBlk->block_size = sBlk->block_size_1; ++#else ++ if(sBlk->s_major != SQUASHFS_MAJOR || sBlk->s_minor > SQUASHFS_MINOR) { ++ SERROR("Major/Minor mismatch, filesystem is (%d:%d), I support (%d: <= %d)\n", ++ sBlk->s_major, sBlk->s_minor, SQUASHFS_MAJOR, SQUASHFS_MINOR); ++ goto failed_mount; ++ } ++#endif ++ ++ TRACE("Found valid superblock on %s\n", bdevname(dev)); ++ TRACE("Inodes are %scompressed\n", SQUASHFS_UNCOMPRESSED_INODES(sBlk->flags) ? "un" : ""); ++ TRACE("Data is %scompressed\n", SQUASHFS_UNCOMPRESSED_DATA(sBlk->flags) ? "un" : ""); ++ TRACE("Check data is %s present in the filesystem\n", SQUASHFS_CHECK_DATA(sBlk->flags) ? "" : "not"); ++ TRACE("Filesystem size %d bytes\n", sBlk->bytes_used); ++ TRACE("Block size %d\n", sBlk->block_size); ++ TRACE("Number of inodes %d\n", sBlk->inodes); ++ if(sBlk->s_major > 1) ++ TRACE("Number of fragments %d\n", sBlk->fragments); ++ TRACE("Number of uids %d\n", sBlk->no_uids); ++ TRACE("Number of gids %d\n", sBlk->no_guids); ++ TRACE("sBlk->inode_table_start %x\n", sBlk->inode_table_start); ++ TRACE("sBlk->directory_table_start %x\n", sBlk->directory_table_start); ++ if(sBlk->s_major > 1) ++ TRACE("sBlk->fragment_table_start %x\n", sBlk->fragment_table_start); ++ TRACE("sBlk->uid_start %x\n", sBlk->uid_start); ++ ++ s->s_flags |= MS_RDONLY; ++ s->s_op = &squashfs_ops; ++ ++ /* Init inode_table block pointer array */ ++ if(!(msBlk->block_cache = (squashfs_cache *) kmalloc(sizeof(squashfs_cache) * SQUASHFS_CACHED_BLKS, GFP_KERNEL))) { ++ ERROR("Failed to allocate block cache\n"); ++ goto failed_mount; ++ } ++ ++ for(i = 0; i < SQUASHFS_CACHED_BLKS; i++) ++ msBlk->block_cache[i].block = SQUASHFS_INVALID_BLK; ++ ++ msBlk->next_cache = 0; ++ ++ /* Allocate read_data block */ ++ msBlk->read_size = (sBlk->block_size < SQUASHFS_METADATA_SIZE) ? SQUASHFS_METADATA_SIZE : sBlk->block_size; ++ if(!(msBlk->read_data = (char *) kmalloc(msBlk->read_size, GFP_KERNEL))) { ++ ERROR("Failed to allocate read_data block\n"); ++ goto failed_mount1; ++ } ++ ++ /* Allocate read_page block */ ++ if(sBlk->block_size > PAGE_CACHE_SIZE && ++ !(msBlk->read_page = (char *) kmalloc(sBlk->block_size, GFP_KERNEL))) { ++ ERROR("Failed to allocate read_page block\n"); ++ goto failed_mount2; ++ } ++ ++ /* Allocate uid and gid tables */ ++ if(!(msBlk->uid = (squashfs_uid *) kmalloc((sBlk->no_uids + ++ sBlk->no_guids) * sizeof(squashfs_uid), GFP_KERNEL))) { ++ ERROR("Failed to allocate uid/gid table\n"); ++ goto failed_mount3; ++ } ++ msBlk->guid = msBlk->uid + sBlk->no_uids; ++ ++ if(msBlk->swap) { ++ squashfs_uid suid[sBlk->no_uids + sBlk->no_guids]; ++ ++ if(!read_data(s, (char *) &suid, sBlk->uid_start, ((sBlk->no_uids + sBlk->no_guids) * ++ sizeof(squashfs_uid)) | SQUASHFS_COMPRESSED_BIT, 0, NULL)) { ++ SERROR("unable to read uid/gid table\n"); ++ goto failed_mount4; ++ } ++ SQUASHFS_SWAP_DATA(msBlk->uid, suid, (sBlk->no_uids + sBlk->no_guids), (sizeof(squashfs_uid) * 8)); ++ } else ++ if(!read_data(s, (char *) msBlk->uid, sBlk->uid_start, ((sBlk->no_uids + sBlk->no_guids) * ++ sizeof(squashfs_uid)) | SQUASHFS_COMPRESSED_BIT, 0, NULL)) { ++ SERROR("unable to read uid/gid table\n"); ++ goto failed_mount4; ++ } ++ ++ ++#ifdef SQUASHFS_1_0_COMPATIBILITY ++ if(sBlk->s_major == 1) { ++ msBlk->iget = squashfs_iget_1; ++ msBlk->read_blocklist = read_blocklist_1; ++ msBlk->fragment = (struct squashfs_fragment_cache *) msBlk->fragment_index = NULL; ++ goto allocate_root; ++ } ++#endif ++ msBlk->iget = squashfs_iget; ++ msBlk->read_blocklist = read_blocklist; ++ ++ if(!(msBlk->fragment = (struct squashfs_fragment_cache *) kmalloc(sizeof(struct squashfs_fragment_cache) * SQUASHFS_CACHED_FRAGMENTS, GFP_KERNEL))) { ++ ERROR("Failed to allocate fragment block cache\n"); ++ goto failed_mount4; ++ } ++ ++ for(i = 0; i < SQUASHFS_CACHED_FRAGMENTS; i++) { ++ msBlk->fragment[i].locked = 0; ++ msBlk->fragment[i].block = SQUASHFS_INVALID_BLK; ++ msBlk->fragment[i].data = NULL; ++ } ++ ++ msBlk->next_fragment = 0; ++ ++ /* Allocate fragment index table */ ++ if(!(msBlk->fragment_index = (squashfs_fragment_index *) kmalloc(SQUASHFS_FRAGMENT_INDEX_BYTES(sBlk->fragments), GFP_KERNEL))) { ++ ERROR("Failed to allocate uid/gid table\n"); ++ goto failed_mount5; ++ } ++ ++ if(SQUASHFS_FRAGMENT_INDEX_BYTES(sBlk->fragments) && ++ !read_data(s, (char *) msBlk->fragment_index, sBlk->fragment_table_start, ++ SQUASHFS_FRAGMENT_INDEX_BYTES(sBlk->fragments) | SQUASHFS_COMPRESSED_BIT, 0, NULL)) { ++ SERROR("unable to read fragment index table\n"); ++ goto failed_mount6; ++ } ++ ++ if(msBlk->swap) { ++ int i; ++ squashfs_fragment_index fragment; ++ ++ for(i = 0; i < SQUASHFS_FRAGMENT_INDEXES(sBlk->fragments); i++) { ++ SQUASHFS_SWAP_FRAGMENT_INDEXES((&fragment), &msBlk->fragment_index[i], 1); ++ msBlk->fragment_index[i] = fragment; ++ } ++ } ++ ++#ifdef SQUASHFS_1_0_COMPATIBILITY ++allocate_root: ++#endif ++ if(!(s->s_root = d_alloc_root((msBlk->iget)(s, sBlk->root_inode)))) { ++ ERROR("Root inode create failed\n"); ++ goto failed_mount5; ++ } ++ ++ TRACE("Leaving squashfs_read_super\n"); ++ return s; ++ ++failed_mount6: ++ kfree(msBlk->fragment_index); ++failed_mount5: ++ kfree(msBlk->fragment); ++failed_mount4: ++ kfree(msBlk->uid); ++failed_mount3: ++ kfree(msBlk->read_page); ++failed_mount2: ++ kfree(msBlk->read_data); ++failed_mount1: ++ kfree(msBlk->block_cache); ++failed_mount: ++ return NULL; ++} ++ ++ ++static int squashfs_statfs(struct super_block *s, struct statfs *buf) ++{ ++ squashfs_super_block *sBlk = &s->u.squashfs_sb.sBlk; ++ ++ TRACE("Entered squashfs_statfs\n"); ++ buf->f_type = SQUASHFS_MAGIC; ++ buf->f_bsize = sBlk->block_size; ++ buf->f_blocks = ((sBlk->bytes_used - 1) >> sBlk->block_log) + 1; ++ buf->f_bfree = buf->f_bavail = 0; ++ buf->f_files = sBlk->inodes; ++ buf->f_ffree = 0; ++ buf->f_namelen = SQUASHFS_NAME_LEN; ++ return 0; ++} ++ ++ ++static int squashfs_symlink_readpage(struct file *file, struct page *page) ++{ ++ struct inode *inode = page->mapping->host; ++ int index = page->index << PAGE_CACHE_SHIFT, length, bytes; ++ int block = inode->u.squashfs_i.start_block; ++ int offset = inode->u.squashfs_i.offset; ++ void *pageaddr = kmap(page); ++ ++ TRACE("Entered squashfs_symlink_readpage, page index %x, start block %x, offset %x\n", ++ (unsigned int) page->index, inode->u.squashfs_i.start_block, inode->u.squashfs_i.offset); ++ ++ for(length = 0; length < index; length += bytes) { ++ if(!(bytes = squashfs_get_cached_block(inode->i_sb, NULL, block, offset, ++ PAGE_CACHE_SIZE, &block, &offset))) { ++ ERROR("Unable to read symbolic link [%x:%x]\n", block, offset); ++ goto skip_read; ++ } ++ } ++ ++ if(length != index) { ++ ERROR("(squashfs_symlink_readpage) length != index\n"); ++ bytes = 0; ++ goto skip_read; ++ } ++ ++ bytes = (inode->i_size - length) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE : inode->i_size - length; ++ if(!(bytes = squashfs_get_cached_block(inode->i_sb, pageaddr, block, offset, bytes, &block, &offset))) ++ ERROR("Unable to read symbolic link [%x:%x]\n", block, offset); ++ ++skip_read: ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); ++ kunmap(page); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ UnlockPage(page); ++ ++ return 0; ++} ++ ++ ++#define SIZE 256 ++ ++#ifdef SQUASHFS_1_0_COMPATIBILITY ++static unsigned int read_blocklist_1(struct inode *inode, int index, int readahead_blks, ++ char *block_list, char **block_p, unsigned int *bsize) ++{ ++ squashfs_sb_info *msBlk = &inode->i_sb->u.squashfs_sb; ++ unsigned short *block_listp; ++ int i = 0; ++ int block_ptr = inode->u.squashfs_i.block_list_start; ++ int offset = inode->u.squashfs_i.offset; ++ int block = inode->u.squashfs_i.start_block; ++ ++ for(;;) { ++ int blocks = (index + readahead_blks - i); ++ if(blocks > (SIZE >> 1)) { ++ if((index - i) <= (SIZE >> 1)) ++ blocks = index - i; ++ else ++ blocks = SIZE >> 1; ++ } ++ ++ if(msBlk->swap) { ++ unsigned char sblock_list[SIZE]; ++ if(!squashfs_get_cached_block(inode->i_sb, (char *) sblock_list, block_ptr, offset, blocks << 1, &block_ptr, &offset)) { ++ ERROR("Unable to read block list [%d:%x]\n", block_ptr, offset); ++ return 0; ++ } ++ SQUASHFS_SWAP_SHORTS(((unsigned short *)block_list), ((unsigned short *)sblock_list), blocks); ++ } else ++ if(!squashfs_get_cached_block(inode->i_sb, (char *) block_list, block_ptr, offset, blocks << 1, &block_ptr, &offset)) { ++ ERROR("Unable to read block list [%d:%x]\n", block_ptr, offset); ++ return 0; ++ } ++ for(block_listp = (unsigned short *) block_list; i < index && blocks; i ++, block_listp ++, blocks --) ++ block += SQUASHFS_COMPRESSED_SIZE(*block_listp); ++ if(blocks >= readahead_blks) ++ break; ++ } ++ ++ if(bsize) ++ *bsize = SQUASHFS_COMPRESSED_SIZE(*block_listp) | (!SQUASHFS_COMPRESSED(*block_listp) ? SQUASHFS_COMPRESSED_BIT_BLOCK : 0); ++ else ++ (unsigned short *) *block_p = block_listp; ++ return block; ++} ++#endif ++ ++ ++ ++static unsigned int read_blocklist(struct inode *inode, int index, int readahead_blks, ++ char *block_list, char **block_p, unsigned int *bsize) ++{ ++ squashfs_sb_info *msBlk = &inode->i_sb->u.squashfs_sb; ++ unsigned int *block_listp; ++ int i = 0; ++ int block_ptr = inode->u.squashfs_i.block_list_start; ++ int offset = inode->u.squashfs_i.offset; ++ int block = inode->u.squashfs_i.start_block; ++ ++ for(;;) { ++ int blocks = (index + readahead_blks - i); ++ if(blocks > (SIZE >> 2)) { ++ if((index - i) <= (SIZE >> 2)) ++ blocks = index - i; ++ else ++ blocks = SIZE >> 2; ++ } ++ ++ if(msBlk->swap) { ++ unsigned char sblock_list[SIZE]; ++ if(!squashfs_get_cached_block(inode->i_sb, (char *) sblock_list, block_ptr, offset, blocks << 2, &block_ptr, &offset)) { ++ ERROR("Unable to read block list [%d:%x]\n", block_ptr, offset); ++ return 0; ++ } ++ SQUASHFS_SWAP_INTS(((unsigned int *)block_list), ((unsigned int *)sblock_list), blocks); ++ } else ++ if(!squashfs_get_cached_block(inode->i_sb, (char *) block_list, block_ptr, offset, blocks << 2, &block_ptr, &offset)) { ++ ERROR("Unable to read block list [%d:%x]\n", block_ptr, offset); ++ return 0; ++ } ++ for(block_listp = (unsigned int *) block_list; i < index && blocks; i ++, block_listp ++, blocks --) ++ block += SQUASHFS_COMPRESSED_SIZE_BLOCK(*block_listp); ++ if(blocks >= readahead_blks) ++ break; ++ } ++ ++ *bsize = *block_listp; ++ return block; ++} ++ ++ ++static int squashfs_readpage(struct file *file, struct page *page) ++{ ++ struct inode *inode = page->mapping->host; ++ squashfs_sb_info *msBlk = &inode->i_sb->u.squashfs_sb; ++ squashfs_super_block *sBlk = &msBlk->sBlk; ++ unsigned char block_list[SIZE]; ++ unsigned int bsize, block, i = 0, bytes = 0, byte_offset = 0; ++ int index = page->index >> (sBlk->block_log - PAGE_CACHE_SHIFT); ++ void *pageaddr = kmap(page); ++ struct squashfs_fragment_cache *fragment; ++ char *data_ptr = msBlk->read_page; ++ ++ int mask = (1 << (sBlk->block_log - PAGE_CACHE_SHIFT)) - 1; ++ int start_index = page->index & ~mask; ++ int end_index = start_index | mask; ++ ++ TRACE("Entered squashfs_readpage, page index %x, start block %x\n", (unsigned int) page->index, ++ inode->u.squashfs_i.start_block); ++ ++ if(inode->u.squashfs_i.fragment_start_block == SQUASHFS_INVALID_BLK || index < (inode->i_size >> sBlk->block_log)) { ++ if((block = (msBlk->read_blocklist)(inode, index, 1, block_list, NULL, &bsize)) == 0) ++ goto skip_read; ++ ++ down(&msBlk->read_page_mutex); ++ if(!(bytes = read_data(inode->i_sb, msBlk->read_page, block, bsize, 1, NULL))) { ++ ERROR("Unable to read page, block %x, size %x\n", block, bsize); ++ up(&msBlk->read_page_mutex); ++ goto skip_read; ++ } ++ } else { ++ if((fragment = get_cached_fragment(inode->i_sb, inode->u.squashfs_i.fragment_start_block, inode->u.squashfs_i.fragment_size)) == NULL) { ++ ERROR("Unable to read page, block %x, size %x\n", inode->u.squashfs_i.fragment_start_block, (int) inode->u.squashfs_i.fragment_size); ++ goto skip_read; ++ } ++ bytes = inode->u.squashfs_i.fragment_offset + (inode->i_size & (sBlk->block_size - 1)); ++ byte_offset = inode->u.squashfs_i.fragment_offset; ++ data_ptr = fragment->data; ++ } ++ ++ for(i = start_index; i <= end_index && byte_offset < bytes; i++, byte_offset += PAGE_CACHE_SIZE) { ++ struct page *push_page; ++ int available_bytes = (bytes - byte_offset) > PAGE_CACHE_SIZE ? PAGE_CACHE_SIZE : bytes - byte_offset; ++ ++ TRACE("bytes %d, i %d, byte_offset %d, available_bytes %d\n", bytes, i, byte_offset, available_bytes); ++ ++ if(i == page->index) { ++ memcpy(pageaddr, data_ptr + byte_offset, available_bytes); ++ memset(pageaddr + available_bytes, 0, PAGE_CACHE_SIZE - available_bytes); ++ kunmap(page); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ UnlockPage(page); ++ } else if((push_page = grab_cache_page_nowait(page->mapping, i))) { ++ void *pageaddr = kmap(push_page); ++ memcpy(pageaddr, data_ptr + byte_offset, available_bytes); ++ memset(pageaddr + available_bytes, 0, PAGE_CACHE_SIZE - available_bytes); ++ kunmap(push_page); ++ flush_dcache_page(push_page); ++ SetPageUptodate(push_page); ++ UnlockPage(push_page); ++ page_cache_release(push_page); ++ } ++ } ++ ++ if(inode->u.squashfs_i.fragment_start_block == SQUASHFS_INVALID_BLK || index < (inode->i_size >> sBlk->block_log)) ++ up(&msBlk->read_page_mutex); ++ else ++ release_cached_fragment(msBlk, fragment); ++ ++ return 0; ++ ++skip_read: ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); ++ kunmap(page); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ UnlockPage(page); ++ ++ return 0; ++} ++ ++ ++static int squashfs_readpage4K(struct file *file, struct page *page) ++{ ++ struct inode *inode = page->mapping->host; ++ squashfs_sb_info *msBlk = &inode->i_sb->u.squashfs_sb; ++ squashfs_super_block *sBlk = &msBlk->sBlk; ++ unsigned char block_list[SIZE]; ++ unsigned int bsize, block, bytes = 0; ++ void *pageaddr = kmap(page); ++ ++ TRACE("Entered squashfs_readpage4K, page index %x, start block %x\n", (unsigned int) page->index, ++ inode->u.squashfs_i.start_block); ++ ++ if(page->index < (inode->i_size >> sBlk->block_log)) { ++ block = (msBlk->read_blocklist)(inode, page->index, 1, block_list, NULL, &bsize); ++ ++ if(!(bytes = read_data(inode->i_sb, pageaddr, block, bsize, 1, NULL))) ++ ERROR("Unable to read page, block %x, size %x\n", block, bsize); ++ } else { ++ struct squashfs_fragment_cache *fragment; ++ ++ if((fragment = get_cached_fragment(inode->i_sb, inode->u.squashfs_i.fragment_start_block, inode->u.squashfs_i.fragment_size)) == NULL) ++ ERROR("Unable to read page, block %x, size %x\n", inode->u.squashfs_i.fragment_start_block, (int) inode->u.squashfs_i.fragment_size); ++ else { ++ bytes = inode->i_size & (sBlk->block_size - 1); ++ memcpy(pageaddr, fragment->data + inode->u.squashfs_i.fragment_offset, bytes); ++ release_cached_fragment(msBlk, fragment); ++ } ++ } ++ ++ memset(pageaddr + bytes, 0, PAGE_CACHE_SIZE - bytes); ++ kunmap(page); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ UnlockPage(page); ++ ++ return 0; ++} ++ ++ ++#ifdef SQUASHFS_1_0_COMPATIBILITY ++static int squashfs_readpage_lessthan4K(struct file *file, struct page *page) ++{ ++ struct inode *inode = page->mapping->host; ++ squashfs_sb_info *msBlk = &inode->i_sb->u.squashfs_sb; ++ squashfs_super_block *sBlk = &msBlk->sBlk; ++ unsigned char block_list[SIZE]; ++ unsigned short *block_listp, block, bytes = 0; ++ int index = page->index << (PAGE_CACHE_SHIFT - sBlk->block_log); ++ int file_blocks = ((inode->i_size - 1) >> sBlk->block_log) + 1; ++ int readahead_blks = 1 << (PAGE_CACHE_SHIFT - sBlk->block_log); ++ void *pageaddr = kmap(page); ++ ++ int i_end = index + (1 << (PAGE_CACHE_SHIFT - sBlk->block_log)); ++ int byte; ++ ++ TRACE("Entered squashfs_readpage_lessthan4K, page index %x, start block %x\n", (unsigned int) page->index, ++ inode->u.squashfs_i.start_block); ++ ++ block = read_blocklist_1(inode, index, readahead_blks, block_list, (char **) &block_listp, NULL); ++ ++ if(i_end > file_blocks) ++ i_end = file_blocks; ++ ++ while(index < i_end) { ++ if(!(byte = read_data(inode->i_sb, pageaddr, block, *block_listp, 0, NULL))) { ++ ERROR("Unable to read page, block %x, size %x\n", block, *block_listp); ++ goto skip_read; ++ } ++ block += SQUASHFS_COMPRESSED_SIZE(*block_listp); ++ pageaddr += byte; ++ bytes += byte; ++ index ++; ++ block_listp ++; ++ } ++ ++skip_read: ++ memset(pageaddr, 0, PAGE_CACHE_SIZE - bytes); ++ kunmap(page); ++ flush_dcache_page(page); ++ SetPageUptodate(page); ++ UnlockPage(page); ++ ++ return 0; ++} ++#endif ++ ++ ++static int squashfs_readdir(struct file *file, void *dirent, filldir_t filldir) ++{ ++ struct inode *i = file->f_dentry->d_inode; ++ squashfs_sb_info *msBlk = &i->i_sb->u.squashfs_sb; ++ squashfs_super_block *sBlk = &msBlk->sBlk; ++ int next_block = i->u.squashfs_i.start_block + sBlk->directory_table_start, next_offset = ++ i->u.squashfs_i.offset, length = 0, dirs_read = 0, dir_count; ++ squashfs_dir_header dirh; ++ char buffer[sizeof(squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1]; ++ squashfs_dir_entry *dire = (squashfs_dir_entry *) buffer; ++ ++ TRACE("Entered squashfs_readdir [%x:%x]\n", next_block, next_offset); ++ ++ while(length < i->i_size) { ++ /* read directory header */ ++ if(msBlk->swap) { ++ squashfs_dir_header sdirh; ++ if(!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, next_block, ++ next_offset, sizeof(sdirh), &next_block, &next_offset)) ++ goto failed_read; ++ length += sizeof(sdirh); ++ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); ++ } else { ++ if(!squashfs_get_cached_block(i->i_sb, (char *) &dirh, next_block, ++ next_offset, sizeof(dirh), &next_block, &next_offset)) ++ goto failed_read; ++ length += sizeof(dirh); ++ } ++ ++ dir_count = dirh.count + 1; ++ while(dir_count--) { ++ if(msBlk->swap) { ++ squashfs_dir_entry sdire; ++ if(!squashfs_get_cached_block(i->i_sb, (char *) &sdire, next_block, ++ next_offset, sizeof(sdire), &next_block, &next_offset)) ++ goto failed_read; ++ length += sizeof(sdire); ++ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); ++ } else { ++ if(!squashfs_get_cached_block(i->i_sb, (char *) dire, next_block, ++ next_offset, sizeof(*dire), &next_block, &next_offset)) ++ goto failed_read; ++ length += sizeof(*dire); ++ } ++ ++ if(!squashfs_get_cached_block(i->i_sb, dire->name, next_block, ++ next_offset, dire->size + 1, &next_block, &next_offset)) ++ goto failed_read; ++ length += dire->size + 1; ++ ++ if(file->f_pos >= length) ++ continue; ++ ++ dire->name[dire->size + 1] = '\0'; ++ ++ TRACE("Calling filldir(%x, %s, %d, %d, %x:%x, %d)\n", (unsigned int) dirent, ++ dire->name, dire->size + 1, (int) file->f_pos, ++ dirh.start_block, dire->offset, squashfs_filetype_table[dire->type]); ++ ++ if(filldir(dirent, dire->name, dire->size + 1, file->f_pos, SQUASHFS_MK_VFS_INODE(dirh.start_block, ++ dire->offset), squashfs_filetype_table[dire->type]) < 0) { ++ TRACE("Filldir returned less than 0\n"); ++ return dirs_read; ++ } ++ ++ file->f_pos = length; ++ dirs_read ++; ++ } ++ } ++ ++ return dirs_read; ++ ++failed_read: ++ ERROR("Unable to read directory block [%x:%x]\n", next_block, next_offset); ++ return 0; ++} ++ ++ ++static struct dentry *squashfs_lookup(struct inode *i, struct dentry *dentry) ++{ ++ const char *name =dentry->d_name.name; ++ int len = dentry->d_name.len; ++ struct inode *inode = NULL; ++ squashfs_sb_info *msBlk = &i->i_sb->u.squashfs_sb; ++ squashfs_super_block *sBlk = &msBlk->sBlk; ++ int next_block = i->u.squashfs_i.start_block + sBlk->directory_table_start, next_offset = ++ i->u.squashfs_i.offset, length = 0, dir_count; ++ squashfs_dir_header dirh; ++ char buffer[sizeof(squashfs_dir_entry) + SQUASHFS_NAME_LEN]; ++ squashfs_dir_entry *dire = (squashfs_dir_entry *) buffer; ++ ++ TRACE("Entered squashfs_lookup [%x:%x]\n", next_block, next_offset); ++ ++ while(length < i->i_size) { ++ /* read directory header */ ++ if(msBlk->swap) { ++ squashfs_dir_header sdirh; ++ if(!squashfs_get_cached_block(i->i_sb, (char *) &sdirh, next_block, next_offset, ++ sizeof(sdirh), &next_block, &next_offset)) ++ goto failed_read; ++ length += sizeof(sdirh); ++ SQUASHFS_SWAP_DIR_HEADER(&dirh, &sdirh); ++ } else { ++ if(!squashfs_get_cached_block(i->i_sb, (char *) &dirh, next_block, next_offset, ++ sizeof(dirh), &next_block, &next_offset)) ++ goto failed_read; ++ length += sizeof(dirh); ++ } ++ ++ dir_count = dirh.count + 1; ++ while(dir_count--) { ++ if(msBlk->swap) { ++ squashfs_dir_entry sdire; ++ if(!squashfs_get_cached_block(i->i_sb, (char *) &sdire, ++ next_block,next_offset, sizeof(sdire), &next_block, &next_offset)) ++ goto failed_read; ++ length += sizeof(sdire); ++ SQUASHFS_SWAP_DIR_ENTRY(dire, &sdire); ++ } else { ++ if(!squashfs_get_cached_block(i->i_sb, (char *) dire, ++ next_block,next_offset, sizeof(*dire), &next_block, &next_offset)) ++ goto failed_read; ++ length += sizeof(*dire); ++ } ++ ++ if(!squashfs_get_cached_block(i->i_sb, dire->name, ++ next_block, next_offset, dire->size + 1, &next_block, &next_offset)) ++ goto failed_read; ++ length += dire->size + 1; ++ ++ if((len == dire->size + 1) && !strncmp(name, dire->name, len)) { ++ squashfs_inode ino = SQUASHFS_MKINODE(dirh.start_block, dire->offset); ++ ++ TRACE("calling squashfs_iget for directory entry %s, inode %x:%x\n", ++ name, dirh.start_block, dire->offset); ++ ++ inode = (msBlk->iget)(i->i_sb, ino); ++ ++ goto exit_loop; ++ } ++ } ++ } ++ ++exit_loop: ++ d_add(dentry, inode); ++ return ERR_PTR(0); ++ ++failed_read: ++ ERROR("Unable to read directory block [%x:%x]\n", next_block, next_offset); ++ goto exit_loop; ++} ++ ++ ++static void squashfs_put_super(struct super_block *s) ++{ ++ if(s->u.squashfs_sb.block_cache) kfree(s->u.squashfs_sb.block_cache); ++ if(s->u.squashfs_sb.read_data) kfree(s->u.squashfs_sb.read_data); ++ if(s->u.squashfs_sb.read_page) kfree(s->u.squashfs_sb.read_page); ++ if(s->u.squashfs_sb.uid) kfree(s->u.squashfs_sb.uid); ++ s->u.squashfs_sb.block_cache = (void *) s->u.squashfs_sb.uid = ++ s->u.squashfs_sb.read_data = s->u.squashfs_sb.read_page = NULL; ++} ++ ++ ++static int __init init_squashfs_fs(void) ++{ ++ ++ if(!(stream.workspace = (char *) vmalloc(zlib_inflate_workspacesize()))) { ++ ERROR("Failed to allocate zlib workspace\n"); ++ return -ENOMEM; ++ } ++ return register_filesystem(&squashfs_fs_type); ++} ++ ++ ++static void __exit exit_squashfs_fs(void) ++{ ++ vfree(stream.workspace); ++ unregister_filesystem(&squashfs_fs_type); ++} ++ ++ ++EXPORT_NO_SYMBOLS; ++ ++module_init(init_squashfs_fs); ++module_exit(exit_squashfs_fs); ++MODULE_DESCRIPTION("squashfs, a compressed read-only filesystem"); ++MODULE_AUTHOR("Phillip Lougher "); ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.orig/include/linux/fs.h src/linux/linux/include/linux/fs.h +--- src/linux/linux.orig/include/linux/fs.h 2003-07-04 04:12:25.000000000 -0400 ++++ src/linux/linux/include/linux/fs.h 2004-05-25 21:13:03.000000000 -0400 +@@ -313,6 +313,7 @@ + #include + #include + #include ++#include + + /* + * Attribute flags. These should be or-ed together to figure out what +@@ -503,6 +504,7 @@ + struct socket socket_i; + struct usbdev_inode_info usbdev_i; + struct jffs2_inode_info jffs2_i; ++ struct squashfs_inode_info squashfs_i; + void *generic_ip; + } u; + }; +@@ -697,6 +699,7 @@ + #include + #include + #include ++#include + + extern struct list_head super_blocks; + extern spinlock_t sb_lock; +@@ -755,6 +758,7 @@ + struct usbdev_sb_info usbdevfs_sb; + struct jffs2_sb_info jffs2_sb; + struct cramfs_sb_info cramfs_sb; ++ struct squashfs_sb_info squashfs_sb; + void *generic_sbp; + } u; + /* +diff -Nurb src/linux/linux.orig/include/linux/squashfs_fs.h src/linux/linux/include/linux/squashfs_fs.h +--- src/linux/linux.orig/include/linux/squashfs_fs.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/squashfs_fs.h 2004-05-25 21:13:03.000000000 -0400 +@@ -0,0 +1,474 @@ ++#ifndef SQUASHFS_FS ++#define SQUASHFS_FS ++/* ++ * Squashfs ++ * ++ * Copyright (c) 2002, 2003, 2004 Phillip Lougher ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2, ++ * or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs_fs.h ++ */ ++ ++#define SQUASHFS_MAJOR 2 ++#define SQUASHFS_MINOR 0 ++#define SQUASHFS_MAGIC 0x73717368 ++#define SQUASHFS_MAGIC_SWAP 0x68737173 ++#define SQUASHFS_START 0 ++ ++/* size of metadata (inode and directory) blocks */ ++#define SQUASHFS_METADATA_SIZE 8192 ++#define SQUASHFS_METADATA_LOG 13 ++ ++/* default size of data blocks */ ++#define SQUASHFS_FILE_SIZE 65536 ++#define SQUASHFS_FILE_LOG 16 ++ ++#define SQUASHFS_FILE_MAX_SIZE 65536 ++ ++/* Max number of uids and gids */ ++#define SQUASHFS_UIDS 256 ++#define SQUASHFS_GUIDS 255 ++ ++/* Max length of filename (not 255) */ ++#define SQUASHFS_NAME_LEN 256 ++ ++#define SQUASHFS_INVALID ((long long) 0xffffffffffff) ++#define SQUASHFS_INVALID_BLK ((long long) 0xffffffff) ++#define SQUASHFS_USED_BLK ((long long) 0xfffffffe) ++ ++/* Filesystem flags */ ++#define SQUASHFS_NOI 0 ++#define SQUASHFS_NOD 1 ++#define SQUASHFS_CHECK 2 ++#define SQUASHFS_NOF 3 ++#define SQUASHFS_NO_FRAG 4 ++#define SQUASHFS_ALWAYS_FRAG 5 ++#define SQUASHFS_DUPLICATE 6 ++#define SQUASHFS_BIT(flag, bit) ((flag >> bit) & 1) ++#define SQUASHFS_UNCOMPRESSED_INODES(flags) SQUASHFS_BIT(flags, SQUASHFS_NOI) ++#define SQUASHFS_UNCOMPRESSED_DATA(flags) SQUASHFS_BIT(flags, SQUASHFS_NOD) ++#define SQUASHFS_UNCOMPRESSED_FRAGMENTS(flags) SQUASHFS_BIT(flags, SQUASHFS_NOF) ++#define SQUASHFS_NO_FRAGMENTS(flags) SQUASHFS_BIT(flags, SQUASHFS_NO_FRAG) ++#define SQUASHFS_ALWAYS_FRAGMENTS(flags) SQUASHFS_BIT(flags, SQUASHFS_ALWAYS_FRAG) ++#define SQUASHFS_DUPLICATES(flags) SQUASHFS_BIT(flags, SQUASHFS_DUPLICATE) ++#define SQUASHFS_CHECK_DATA(flags) SQUASHFS_BIT(flags, SQUASHFS_CHECK) ++#define SQUASHFS_MKFLAGS(noi, nod, check_data, nof, no_frag, always_frag, duplicate_checking) (noi | (nod << 1) | (check_data << 2) | (nof << 3) | (no_frag << 4) | (always_frag << 5) | (duplicate_checking << 6)) ++ ++/* Max number of types and file types */ ++#define SQUASHFS_DIR_TYPE 1 ++#define SQUASHFS_FILE_TYPE 2 ++#define SQUASHFS_SYMLINK_TYPE 3 ++#define SQUASHFS_BLKDEV_TYPE 4 ++#define SQUASHFS_CHRDEV_TYPE 5 ++#define SQUASHFS_FIFO_TYPE 6 ++#define SQUASHFS_SOCKET_TYPE 7 ++ ++/* 1.0 filesystem type definitions */ ++#define SQUASHFS_TYPES 5 ++#define SQUASHFS_IPC_TYPE 0 ++ ++/* Flag whether block is compressed or uncompressed, bit is set if block is uncompressed */ ++#define SQUASHFS_COMPRESSED_BIT (1 << 15) ++#define SQUASHFS_COMPRESSED_SIZE(B) (((B) & ~SQUASHFS_COMPRESSED_BIT) ? \ ++ (B) & ~SQUASHFS_COMPRESSED_BIT : SQUASHFS_COMPRESSED_BIT) ++ ++#define SQUASHFS_COMPRESSED(B) (!((B) & SQUASHFS_COMPRESSED_BIT)) ++ ++#define SQUASHFS_COMPRESSED_BIT_BLOCK (1 << 24) ++#define SQUASHFS_COMPRESSED_SIZE_BLOCK(B) (((B) & ~SQUASHFS_COMPRESSED_BIT_BLOCK) ? \ ++ (B) & ~SQUASHFS_COMPRESSED_BIT_BLOCK : SQUASHFS_COMPRESSED_BIT_BLOCK) ++ ++#define SQUASHFS_COMPRESSED_BLOCK(B) (!((B) & SQUASHFS_COMPRESSED_BIT_BLOCK)) ++ ++/* ++ * Inode number ops. Inodes consist of a compressed block number, and an uncompressed ++ * offset within that block ++ */ ++#define SQUASHFS_INODE_BLK(a) ((unsigned int) ((a) >> 16)) ++#define SQUASHFS_INODE_OFFSET(a) ((unsigned int) ((a) & 0xffff)) ++#define SQUASHFS_MKINODE(A, B) ((squashfs_inode)(((squashfs_inode) (A) << 16)\ ++ + (B))) ++ ++/* Compute 32 bit VFS inode number from squashfs inode number */ ++#define SQUASHFS_MK_VFS_INODE(a, b) ((unsigned int) (((a) << 8) + ((b) >> 2) + 1)) ++ ++/* Translate between VFS mode and squashfs mode */ ++#define SQUASHFS_MODE(a) ((a) & 0xfff) ++ ++/* fragment and fragment table defines */ ++typedef unsigned int squashfs_fragment_index; ++#define SQUASHFS_FRAGMENT_BYTES(A) (A * sizeof(squashfs_fragment_entry)) ++#define SQUASHFS_FRAGMENT_INDEX(A) (SQUASHFS_FRAGMENT_BYTES(A) / SQUASHFS_METADATA_SIZE) ++#define SQUASHFS_FRAGMENT_INDEX_OFFSET(A) (SQUASHFS_FRAGMENT_BYTES(A) % SQUASHFS_METADATA_SIZE) ++#define SQUASHFS_FRAGMENT_INDEXES(A) ((SQUASHFS_FRAGMENT_BYTES(A) + SQUASHFS_METADATA_SIZE - 1) / SQUASHFS_METADATA_SIZE) ++#define SQUASHFS_FRAGMENT_INDEX_BYTES(A) (SQUASHFS_FRAGMENT_INDEXES(A) * sizeof(squashfs_fragment_index)) ++#define SQUASHFS_CACHED_FRAGMENTS 3 ++ ++/* cached data constants for filesystem */ ++#define SQUASHFS_CACHED_BLKS 8 ++ ++#define SQUASHFS_MAX_FILE_SIZE_LOG 32 ++#define SQUASHFS_MAX_FILE_SIZE ((long long) 1 << (SQUASHFS_MAX_FILE_SIZE_LOG - 1)) ++ ++#define SQUASHFS_MARKER_BYTE 0xff ++ ++/* ++ * definitions for structures on disk ++ */ ++ ++typedef unsigned int squashfs_block; ++typedef long long squashfs_inode; ++ ++typedef unsigned int squashfs_uid; ++ ++typedef struct squashfs_super_block { ++ unsigned int s_magic; ++ unsigned int inodes; ++ unsigned int bytes_used; ++ unsigned int uid_start; ++ unsigned int guid_start; ++ unsigned int inode_table_start; ++ unsigned int directory_table_start; ++ unsigned int s_major:16; ++ unsigned int s_minor:16; ++ unsigned int block_size_1:16; ++ unsigned int block_log:16; ++ unsigned int flags:8; ++ unsigned int no_uids:8; ++ unsigned int no_guids:8; ++ time_t mkfs_time /* time of filesystem creation */; ++ squashfs_inode root_inode; ++ unsigned int block_size; ++ unsigned int fragments; ++ unsigned int fragment_table_start; ++} __attribute__ ((packed)) squashfs_super_block; ++ ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++} __attribute__ ((packed)) squashfs_base_inode_header; ++ ++typedef squashfs_base_inode_header squashfs_ipc_inode_header; ++ ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned short rdev; ++} __attribute__ ((packed)) squashfs_dev_inode_header; ++ ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned short symlink_size; ++ char symlink[0]; ++} __attribute__ ((packed)) squashfs_symlink_inode_header; ++ ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ time_t mtime; ++ squashfs_block start_block; ++ unsigned int fragment; ++ unsigned int offset; ++ unsigned int file_size:SQUASHFS_MAX_FILE_SIZE_LOG; ++ unsigned short block_list[0]; ++} __attribute__ ((packed)) squashfs_reg_inode_header; ++ ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:8; /* index into uid table */ ++ unsigned int guid:8; /* index into guid table */ ++ unsigned int file_size:19; ++ unsigned int offset:13; ++ time_t mtime; ++ unsigned int start_block:24; ++} __attribute__ ((packed)) squashfs_dir_inode_header; ++ ++typedef union { ++ squashfs_base_inode_header base; ++ squashfs_dev_inode_header dev; ++ squashfs_symlink_inode_header symlink; ++ squashfs_reg_inode_header reg; ++ squashfs_dir_inode_header dir; ++ squashfs_ipc_inode_header ipc; ++} squashfs_inode_header; ++ ++typedef struct { ++ unsigned int offset:13; ++ unsigned int type:3; ++ unsigned int size:8; ++ char name[0]; ++} __attribute__ ((packed)) squashfs_dir_entry; ++ ++typedef struct { ++ unsigned int count:8; ++ unsigned int start_block:24; ++} __attribute__ ((packed)) squashfs_dir_header; ++ ++ ++typedef struct { ++ unsigned int start_block; ++ unsigned int size; ++} __attribute__ ((packed)) squashfs_fragment_entry; ++ ++extern int squashfs_uncompress_block(void *d, int dstlen, void *s, int srclen); ++extern int squashfs_uncompress_init(void); ++extern int squashfs_uncompress_exit(void); ++ ++/* ++ * macros to convert each packed bitfield structure from little endian to big ++ * endian and vice versa. These are needed when creating or using a filesystem on a ++ * machine with different byte ordering to the target architecture. ++ * ++ */ ++ ++#define SQUASHFS_SWAP_SUPER_BLOCK(s, d) {\ ++ SQUASHFS_MEMSET(s, d, sizeof(squashfs_super_block));\ ++ SQUASHFS_SWAP((s)->s_magic, d, 0, 32);\ ++ SQUASHFS_SWAP((s)->inodes, d, 32, 32);\ ++ SQUASHFS_SWAP((s)->bytes_used, d, 64, 32);\ ++ SQUASHFS_SWAP((s)->uid_start, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->guid_start, d, 128, 32);\ ++ SQUASHFS_SWAP((s)->inode_table_start, d, 160, 32);\ ++ SQUASHFS_SWAP((s)->directory_table_start, d, 192, 32);\ ++ SQUASHFS_SWAP((s)->s_major, d, 224, 16);\ ++ SQUASHFS_SWAP((s)->s_minor, d, 240, 16);\ ++ SQUASHFS_SWAP((s)->block_size_1, d, 256, 16);\ ++ SQUASHFS_SWAP((s)->block_log, d, 272, 16);\ ++ SQUASHFS_SWAP((s)->flags, d, 288, 8);\ ++ SQUASHFS_SWAP((s)->no_uids, d, 296, 8);\ ++ SQUASHFS_SWAP((s)->no_guids, d, 304, 8);\ ++ SQUASHFS_SWAP((s)->mkfs_time, d, 312, 32);\ ++ SQUASHFS_SWAP((s)->root_inode, d, 344, 64);\ ++ SQUASHFS_SWAP((s)->block_size, d, 408, 32);\ ++ SQUASHFS_SWAP((s)->fragments, d, 440, 32);\ ++ SQUASHFS_SWAP((s)->fragment_table_start, d, 472, 32);\ ++} ++ ++#define SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, n) {\ ++ SQUASHFS_MEMSET(s, d, n);\ ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ ++ SQUASHFS_SWAP((s)->uid, d, 16, 8);\ ++ SQUASHFS_SWAP((s)->guid, d, 24, 8);\ ++} ++ ++#define SQUASHFS_SWAP_IPC_INODE_HEADER(s, d) SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_ipc_inode_header)) ++ ++#define SQUASHFS_SWAP_DEV_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_dev_inode_header));\ ++ SQUASHFS_SWAP((s)->rdev, d, 32, 16);\ ++} ++ ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_symlink_inode_header));\ ++ SQUASHFS_SWAP((s)->symlink_size, d, 32, 16);\ ++} ++ ++#define SQUASHFS_SWAP_REG_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_reg_inode_header));\ ++ SQUASHFS_SWAP((s)->mtime, d, 32, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 64, 32);\ ++ SQUASHFS_SWAP((s)->fragment, d, 96, 32);\ ++ SQUASHFS_SWAP((s)->offset, d, 128, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 160, SQUASHFS_MAX_FILE_SIZE_LOG);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INODE_HEADER(s, d) {\ ++ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_dir_inode_header));\ ++ SQUASHFS_SWAP((s)->file_size, d, 32, 19);\ ++ SQUASHFS_SWAP((s)->offset, d, 51, 13);\ ++ SQUASHFS_SWAP((s)->mtime, d, 64, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 96, 24);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_HEADER(s, d) {\ ++ SQUASHFS_MEMSET(s, d, sizeof(squashfs_dir_header));\ ++ SQUASHFS_SWAP((s)->count, d, 0, 8);\ ++ SQUASHFS_SWAP((s)->start_block, d, 8, 24);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_ENTRY(s, d) {\ ++ SQUASHFS_MEMSET(s, d, sizeof(squashfs_dir_entry));\ ++ SQUASHFS_SWAP((s)->offset, d, 0, 13);\ ++ SQUASHFS_SWAP((s)->type, d, 13, 3);\ ++ SQUASHFS_SWAP((s)->size, d, 16, 8);\ ++} ++ ++#define SQUASHFS_SWAP_FRAGMENT_ENTRY(s, d) {\ ++ SQUASHFS_MEMSET(s, d, sizeof(squashfs_fragment_entry));\ ++ SQUASHFS_SWAP((s)->start_block, d, 0, 32);\ ++ SQUASHFS_SWAP((s)->size, d, 32, 32);\ ++} ++ ++#define SQUASHFS_SWAP_SHORTS(s, d, n) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_MEMSET(s, d, n * 2);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += 16)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, 16);\ ++} ++ ++#define SQUASHFS_SWAP_INTS(s, d, n) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_MEMSET(s, d, n * 4);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += 32)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, 32);\ ++} ++ ++#define SQUASHFS_SWAP_DATA(s, d, n, bits) {\ ++ int entry;\ ++ int bit_position;\ ++ SQUASHFS_MEMSET(s, d, n * bits / 8);\ ++ for(entry = 0, bit_position = 0; entry < n; entry++, bit_position += bits)\ ++ SQUASHFS_SWAP(s[entry], d, bit_position, bits);\ ++} ++ ++#define SQUASHFS_SWAP_FRAGMENT_INDEXES(s, d, n) SQUASHFS_SWAP_INTS(s, d, n) ++ ++#ifdef SQUASHFS_1_0_COMPATIBILITY ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++} __attribute__ ((packed)) squashfs_base_inode_header_1; ++ ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned int type:4; ++ unsigned int offset:4; ++} __attribute__ ((packed)) squashfs_ipc_inode_header_1; ++ ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned short rdev; ++} __attribute__ ((packed)) squashfs_dev_inode_header_1; ++ ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned short symlink_size; ++ char symlink[0]; ++} __attribute__ ((packed)) squashfs_symlink_inode_header_1; ++ ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ time_t mtime; ++ squashfs_block start_block; ++ unsigned int file_size:SQUASHFS_MAX_FILE_SIZE_LOG; ++ unsigned short block_list[0]; ++} __attribute__ ((packed)) squashfs_reg_inode_header_1; ++ ++typedef struct { ++ unsigned int inode_type:4; ++ unsigned int mode:12; /* protection */ ++ unsigned int uid:4; /* index into uid table */ ++ unsigned int guid:4; /* index into guid table */ ++ unsigned int file_size:19; ++ unsigned int offset:13; ++ time_t mtime; ++ unsigned int start_block:24; ++} __attribute__ ((packed)) squashfs_dir_inode_header_1; ++ ++#define SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, n) {\ ++ SQUASHFS_MEMSET(s, d, n);\ ++ SQUASHFS_SWAP((s)->inode_type, d, 0, 4);\ ++ SQUASHFS_SWAP((s)->mode, d, 4, 12);\ ++ SQUASHFS_SWAP((s)->uid, d, 16, 4);\ ++ SQUASHFS_SWAP((s)->guid, d, 20, 4);\ ++} ++ ++#define SQUASHFS_SWAP_IPC_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, sizeof(squashfs_ipc_inode_header_1));\ ++ SQUASHFS_SWAP((s)->type, d, 24, 4);\ ++ SQUASHFS_SWAP((s)->offset, d, 28, 4);\ ++} ++ ++#define SQUASHFS_SWAP_DEV_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_BASE_INODE_HEADER_1(s, d, sizeof(squashfs_dev_inode_header_1));\ ++ SQUASHFS_SWAP((s)->rdev, d, 24, 16);\ ++} ++ ++#define SQUASHFS_SWAP_SYMLINK_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_symlink_inode_header_1));\ ++ SQUASHFS_SWAP((s)->symlink_size, d, 24, 16);\ ++} ++ ++#define SQUASHFS_SWAP_REG_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_reg_inode_header_1));\ ++ SQUASHFS_SWAP((s)->mtime, d, 24, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 56, 32);\ ++ SQUASHFS_SWAP((s)->file_size, d, 88, SQUASHFS_MAX_FILE_SIZE_LOG);\ ++} ++ ++#define SQUASHFS_SWAP_DIR_INODE_HEADER_1(s, d) {\ ++ SQUASHFS_SWAP_BASE_INODE_HEADER(s, d, sizeof(squashfs_dir_inode_header_1));\ ++ SQUASHFS_SWAP((s)->file_size, d, 24, 19);\ ++ SQUASHFS_SWAP((s)->offset, d, 43, 13);\ ++ SQUASHFS_SWAP((s)->mtime, d, 56, 32);\ ++ SQUASHFS_SWAP((s)->start_block, d, 88, 24);\ ++} ++#endif ++ ++#ifdef __KERNEL__ ++/* ++ * macros used to swap each structure entry, taking into account ++ * bitfields and different bitfield placing conventions on differing architectures ++ */ ++#include ++#ifdef __BIG_ENDIAN ++ /* convert from little endian to big endian */ ++#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, tbits, b_pos) ++#else ++ /* convert from big endian to little endian */ ++#define SQUASHFS_SWAP(value, p, pos, tbits) _SQUASHFS_SWAP(value, p, pos, tbits, 64 - tbits - b_pos) ++#endif ++ ++#define _SQUASHFS_SWAP(value, p, pos, tbits, SHIFT) {\ ++ int bits;\ ++ int b_pos = pos % 8;\ ++ unsigned long long val = 0;\ ++ unsigned char *s = (unsigned char *)p + (pos / 8);\ ++ unsigned char *d = ((unsigned char *) &val) + 7;\ ++ for(bits = 0; bits < (tbits + b_pos); bits += 8) \ ++ *d-- = *s++;\ ++ value = (val >> (SHIFT))/* & ((1 << tbits) - 1)*/;\ ++} ++#define SQUASHFS_MEMSET(s, d, n) memset(s, 0, n); ++#endif ++#endif +diff -Nurb src/linux/linux.orig/include/linux/squashfs_fs_i.h src/linux/linux/include/linux/squashfs_fs_i.h +--- src/linux/linux.orig/include/linux/squashfs_fs_i.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/squashfs_fs_i.h 2004-05-25 21:13:03.000000000 -0400 +@@ -0,0 +1,33 @@ ++#ifndef SQUASHFS_FS_I ++#define SQUASHFS_FS_I ++/* ++ * Squashfs ++ * ++ * Copyright (c) 2002, 2003, 2004 Phillip Lougher ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2, ++ * or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs_fs_i.h ++ */ ++ ++typedef struct squashfs_inode_info { ++ unsigned int start_block; ++ unsigned int block_list_start; ++ unsigned int offset; ++ unsigned int fragment_start_block; ++ unsigned int fragment_size; ++ unsigned int fragment_offset; ++ } squashfs_inode_info; ++#endif +diff -Nurb src/linux/linux.orig/include/linux/squashfs_fs_sb.h src/linux/linux/include/linux/squashfs_fs_sb.h +--- src/linux/linux.orig/include/linux/squashfs_fs_sb.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/squashfs_fs_sb.h 2004-05-25 21:13:03.000000000 -0400 +@@ -0,0 +1,65 @@ ++#ifndef SQUASHFS_FS_SB ++#define SQUASHFS_FS_SB ++/* ++ * Squashfs ++ * ++ * Copyright (c) 2002, 2003, 2004 Phillip Lougher ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version 2, ++ * or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ++ * ++ * squashfs_fs_sb.h ++ */ ++ ++#include ++ ++typedef struct { ++ unsigned int block; ++ int length; ++ unsigned int next_index; ++ char *data; ++ } squashfs_cache; ++ ++struct squashfs_fragment_cache { ++ unsigned int block; ++ int length; ++ unsigned int locked; ++ char *data; ++ }; ++ ++typedef struct squashfs_sb_info { ++ squashfs_super_block sBlk; ++ int devblksize; ++ int devblksize_log2; ++ int swap; ++ squashfs_cache *block_cache; ++ struct squashfs_fragment_cache *fragment; ++ int next_cache; ++ int next_fragment; ++ squashfs_uid *uid; ++ squashfs_uid *guid; ++ squashfs_fragment_index *fragment_index; ++ unsigned int read_size; ++ char *read_data; ++ char *read_page; ++ struct semaphore read_page_mutex; ++ struct semaphore block_cache_mutex; ++ struct semaphore fragment_mutex; ++ wait_queue_head_t waitq; ++ wait_queue_head_t fragment_wait_queue; ++ struct inode *(*iget)(struct super_block *s, squashfs_inode inode); ++ unsigned int (*read_blocklist)(struct inode *inode, int index, int readahead_blks, ++ char *block_list, char **block_p, unsigned int *bsize); ++ } squashfs_sb_info; ++#endif +diff -Nurb src/linux/linux.orig/init/do_mounts.c src/linux/linux/init/do_mounts.c +--- src/linux/linux.orig/init/do_mounts.c 2003-11-08 03:13:20.000000000 -0500 ++++ src/linux/linux/init/do_mounts.c 2004-05-25 21:13:03.000000000 -0400 +@@ -16,6 +16,7 @@ + #include + #include + #include ++#include + + #undef BUILD_CRAMDISK + +@@ -470,6 +471,7 @@ + * ext2 + * romfs + * gzip ++ * squashfs + */ + static int __init + identify_ramdisk_image(int fd, int start_block) +@@ -479,6 +481,7 @@ + struct ext2_super_block *ext2sb; + struct romfs_super_block *romfsb; + struct cramfs_super *cramfsb; ++ struct squashfs_super_block *squashfsb; + int nblocks = -1; + unsigned char *buf; + +@@ -490,6 +493,7 @@ + ext2sb = (struct ext2_super_block *) buf; + romfsb = (struct romfs_super_block *) buf; + cramfsb = (struct cramfs_super *) buf; ++ squashfsb = (struct squashfs_super_block *) buf; + memset(buf, 0xe5, size); + + /* +@@ -536,6 +540,15 @@ + goto done; + } + ++ /* squashfs is at block zero too */ ++ if (squashfsb->s_magic == SQUASHFS_MAGIC) { ++ printk(KERN_NOTICE ++ "RAMDISK: squashfs filesystem found at block %d\n", ++ start_block); ++ nblocks = (squashfsb->bytes_used+BLOCK_SIZE-1)>>BLOCK_SIZE_BITS; ++ goto done; ++ } ++ + /* + * Read block 1 to test for minix and ext2 superblock + */ +diff -Nurb src/linux/linux.orig/kernel/ksyms.c src/linux/linux/kernel/ksyms.c +--- src/linux/linux.orig/kernel/ksyms.c 2003-07-04 04:12:28.000000000 -0400 ++++ src/linux/linux/kernel/ksyms.c 2004-05-25 21:12:24.000000000 -0400 +@@ -482,9 +482,9 @@ + EXPORT_SYMBOL(simple_strtoull); + EXPORT_SYMBOL(system_utsname); /* UTS data */ + EXPORT_SYMBOL(uts_sem); /* UTS semaphore */ +-#ifndef __mips__ ++//#ifndef __mips__ //bite me. -mbm. + EXPORT_SYMBOL(sys_call_table); +-#endif ++//#endif + EXPORT_SYMBOL(machine_restart); + EXPORT_SYMBOL(machine_halt); + EXPORT_SYMBOL(machine_power_off); +diff -Nurb src/linux/linux.orig/lib/Config.in src/linux/linux/lib/Config.in +--- src/linux/linux.orig/lib/Config.in 2003-07-04 04:12:29.000000000 -0400 ++++ src/linux/linux/lib/Config.in 2004-05-25 21:13:03.000000000 -0400 +@@ -8,12 +8,14 @@ + # Do we need the compression support? + # + if [ "$CONFIG_CRAMFS" = "y" -o \ ++ "$CONFIG_SQUASHFS" = "y" -o \ + "$CONFIG_PPP_DEFLATE" = "y" -o \ + "$CONFIG_JFFS2_FS" = "y" -o \ + "$CONFIG_ZISOFS_FS" = "y" ]; then + define_tristate CONFIG_ZLIB_INFLATE y + else + if [ "$CONFIG_CRAMFS" = "m" -o \ ++ "$CONFIG_SQUASHFS" = "m" -o \ + "$CONFIG_PPP_DEFLATE" = "m" -o \ + "$CONFIG_JFFS2_FS" = "m" -o \ + "$CONFIG_ZISOFS_FS" = "m" ]; then diff --git a/obsolete-buildroot/sources/openwrt/kernel/patches/130-nfsswap.patch b/obsolete-buildroot/sources/openwrt/kernel/patches/130-nfsswap.patch new file mode 100644 index 0000000000..bf848c129a --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/kernel/patches/130-nfsswap.patch @@ -0,0 +1,2362 @@ +diff -Nurb src/linux/linux.orig/Documentation/netswap.txt src/linux/linux/Documentation/netswap.txt +--- src/linux/linux.orig/Documentation/netswap.txt 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/Documentation/netswap.txt 2004-05-31 02:18:03.000000000 -0400 +@@ -0,0 +1,51 @@ ++ Swapping over network ++ ++Support for this is enabled via the CONFIG_NETSWAP option, which is ++automatically enabled when enabling swap files located on NFS volumes ++(CONFIG_SWAP_VIA_NFS). ++ ++When swapping to files located on a network file system like NFS or ++CODA or others or to nbd (network block device, see `nbd.txt') ++partitions there is the problem that this requires additional memory, ++besides the page which is currently swapped in or out, probably at ++least two more pages for each page in question. ++ ++This means that not only there needs to be free space left in the swap ++file or the swap partition, but in addition there must be enough free ++memory left in the system to perform the swap out of pages. ++ ++This is particularly painful as receiving data over the network itself ++consumes memory, and this memory is allocated from an interrupt ++context (i.e. in the interrupt handler of the network card). That ++means that on a congested network there are chances that the machine ++runs out of memory, simply because the network device's interrupt ++routines allocate memory faster that it is freed by swapping via ++network. ++ ++To cope with this problem, there is a new socket option `SO_SWAPPING' ++which has to be set on the `SOL_SOCKET' level with setsockopt() (see ++setsockopt(2)). When this option is set on any network socket, then ++the system will start to drop network packets it receives on any other ++socket when the number of free pages falls below a certain threshold. ++ ++This threshold initially is 4 pages less than `freepages.min' (see ++`Documentation/sysctl/vm.txt') but can be tuned using the sysctl ++interface by writing to the file `/proc/sys/net/swapping/threshold' ++ ++There are two other files: ++ ++`/proc/sys/net/swapping/dropped': ++ how many network packets have been dropped so far. This file is ++ writable, writing to it simply sets the counter to the given value ++ (useful for resetting the counter). ++ ++`/proc/sys/net/swapping/sock_count': ++ How many network sockets have the `SO_SWAPPING' option set (read ++ only, of course). ++ ++When using swap-files on NFS volumes, then the `SO_SWAPPING' option is ++set or cleared by swapon/swapoff system calls, so the user need not ++care about it. ++ ++Swapping over the network is insecure unless the data would be ++encrypted, which is not the case with NFS. It is also very slow. +diff -Nurb src/linux/linux.orig/Documentation/nfsswap.txt src/linux/linux/Documentation/nfsswap.txt +--- src/linux/linux.orig/Documentation/nfsswap.txt 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/Documentation/nfsswap.txt 2004-05-31 02:18:03.000000000 -0400 +@@ -0,0 +1,41 @@ ++ Swapping to files on NFS volumes ++ ++To do this you have to say `Y' or `M' to the CONFIG_SWAP_VIA_NFS ++configuration option. When compling support for this as a module you ++should read `Documentation/modules.txt'. For auto-loading of the ++module during the `swapon' system call you have to place a line like ++ ++alias swapfile-mod nfsswap ++ ++in `/etc/modules.conf' (or `/etc/conf.modules', depending on your ++setup). NFS volumes holding swapfile should be mounted with `rsize' ++and `wsize' set to something less than the size of a page, otherwise ++deadlocks caused by memory fragmentation can happen, i.e. mount the ++volume which is to hold the swapfiles with ++ ++mount -t nfs -o rsize=2048,wsize=2048 NFS_SERVER_IP:/server_volume /mount_point ++ ++or set the option in `/etc/fstab'. Read `Documentation/nfsroot.txt' to ++learn how to set mount options for the root file system, if your swap ++files are to be located on the root file system. ++ ++Setting the `rsize' and `wsize' to anything less than PAGE_SIZE is a ++performance hit, so you probably want to have at least two volumes ++mounted, one for the swapfiles, one for the rest. ++ ++You may want to read `Documentation/netswap.txt' as well. ++ ++Swapfiles on NFS volumes can be treated like any other swapfile, ++i.e. ++ ++dd if=/dev/zero of=/swapfiles/SWAPFILE bs=1k count=20480 ++mkswap /swapfiles/SWAPFILE ++swapon /swapfiles/SWAPFILE ++ ++will create a 20M swapfile and tell the system to use it. Actually, ++one could use lseek(2) to create an empty swapfile. This is different ++from swapfiles located on local harddisk. ++ ++Swapping over the network is insecure unless the data would be ++encrypted, which is not the case with NFS. It is also very slow. ++ +diff -Nurb src/linux/linux.orig/drivers/block/blkpg.c src/linux/linux/drivers/block/blkpg.c +--- src/linux/linux.orig/drivers/block/blkpg.c 2003-07-04 04:11:31.000000000 -0400 ++++ src/linux/linux/drivers/block/blkpg.c 2004-05-31 02:18:03.000000000 -0400 +@@ -34,7 +34,7 @@ + #include /* for set_device_ro() */ + #include + #include +-#include /* for is_swap_partition() */ ++#include /* for swap_run_test() */ + #include /* for EXPORT_SYMBOL */ + + #include +@@ -114,6 +114,29 @@ + return 0; + } + ++/* swap_run_test() applies this hook to all swapfiles until it returns ++ * "1". If it never returns "1", the result of swap_run_test() is "0", ++ * otherwise "1". ++ */ ++static int is_swap_partition_hook(unsigned int flags, struct file *swap_file, ++ void *testdata) ++{ ++ kdev_t swap_dev = S_ISBLK(swap_file->f_dentry->d_inode->i_mode) ++ ? swap_file->f_dentry->d_inode->i_rdev : 0; ++ kdev_t dev = *((kdev_t *)testdata); ++ ++ if (flags & SWP_USED && dev == swap_dev) { ++ return 1; ++ } else { ++ return 0; ++ } ++} ++ ++static inline int is_swap_partition(kdev_t dev) ++{ ++ return swap_run_test(is_swap_partition_hook, &dev); ++} ++ + /* + * Delete a partition given by partition number + * +diff -Nurb src/linux/linux.orig/fs/Config.in src/linux/linux/fs/Config.in +--- src/linux/linux.orig/fs/Config.in 2004-05-31 02:02:43.000000000 -0400 ++++ src/linux/linux/fs/Config.in 2004-05-31 02:18:03.000000000 -0400 +@@ -4,6 +4,12 @@ + mainmenu_option next_comment + comment 'File systems' + ++if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then ++ tristate 'Swapping to block devices' CONFIG_BLKDEV_SWAP ++else ++ define_bool CONFIG_BLKDEV_SWAP y ++fi ++ + bool 'Quota support' CONFIG_QUOTA + tristate 'Kernel automounter support' CONFIG_AUTOFS_FS + tristate 'Kernel automounter version 4 support (also supports v3)' CONFIG_AUTOFS4_FS +@@ -110,6 +116,12 @@ + dep_tristate 'NFS file system support' CONFIG_NFS_FS $CONFIG_INET + dep_mbool ' Provide NFSv3 client support' CONFIG_NFS_V3 $CONFIG_NFS_FS + dep_bool ' Root file system on NFS' CONFIG_ROOT_NFS $CONFIG_NFS_FS $CONFIG_IP_PNP ++ if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then ++ dep_tristate ' Swapping via NFS (EXPERIMENTAL)' CONFIG_SWAP_VIA_NFS $CONFIG_NFS_FS ++ if [ "$CONFIG_SWAP_VIA_NFS" = "y" -o "$CONFIG_SWAP_VIA_NFS" = "m" ]; then ++ define_bool CONFIG_NETSWAP y ++ fi ++ fi + + dep_tristate 'NFS server support' CONFIG_NFSD $CONFIG_INET + dep_mbool ' Provide NFSv3 server support' CONFIG_NFSD_V3 $CONFIG_NFSD +diff -Nurb src/linux/linux.orig/fs/Makefile src/linux/linux/fs/Makefile +--- src/linux/linux.orig/fs/Makefile 2004-05-31 02:02:42.000000000 -0400 ++++ src/linux/linux/fs/Makefile 2004-05-31 02:18:03.000000000 -0400 +@@ -8,7 +8,7 @@ + O_TARGET := fs.o + + export-objs := filesystems.o open.o dcache.o buffer.o +-mod-subdirs := nls ++mod-subdirs := nls nfs + + obj-y := open.o read_write.o devices.o file_table.o buffer.o \ + super.o block_dev.o char_dev.o stat.o exec.o pipe.o namei.o \ +@@ -70,6 +70,7 @@ + subdir-$(CONFIG_JFS_FS) += jfs + subdir-$(CONFIG_SQUASHFS) += squashfs + ++obj-$(CONFIG_BLKDEV_SWAP) += blkdev_swap.o + + obj-$(CONFIG_BINFMT_AOUT) += binfmt_aout.o + obj-$(CONFIG_BINFMT_EM86) += binfmt_em86.o +diff -Nurb src/linux/linux.orig/fs/blkdev_swap.c src/linux/linux/fs/blkdev_swap.c +--- src/linux/linux.orig/fs/blkdev_swap.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/fs/blkdev_swap.c 2004-05-31 02:18:03.000000000 -0400 +@@ -0,0 +1,309 @@ ++/* ++ * Swapping to partitions or files located on partitions. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifdef DEBUG_BLKDEV_SWAP ++# define dprintk(fmt...) printk(##fmt) ++#else ++# define dprintk(fmt...) do { /* */ } while (0) ++#endif ++ ++#define BLKDEV_SWAP_ID "blkdev" ++#define BLKDEV_FILE_SWAP_ID "blkdev file" ++ ++/* ++ * Helper function, copied here from buffer.c ++ */ ++ ++/* ++ * Start I/O on a page. ++ * This function expects the page to be locked and may return ++ * before I/O is complete. You then have to check page->locked ++ * and page->uptodate. ++ * ++ * brw_page() is SMP-safe, although it's being called with the ++ * kernel lock held - but the code is ready. ++ * ++ * FIXME: we need a swapper_inode->get_block function to remove ++ * some of the bmap kludges and interface ugliness here. ++ */ ++int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size) ++{ ++ struct buffer_head *head, *bh; ++ ++ if (!PageLocked(page)) ++ panic("brw_page: page not locked for I/O"); ++ ++ if (!page->buffers) ++ create_empty_buffers(page, dev, size); ++ head = bh = page->buffers; ++ ++ /* Stage 1: lock all the buffers */ ++ do { ++ lock_buffer(bh); ++ bh->b_blocknr = *(b++); ++ set_bit(BH_Mapped, &bh->b_state); ++ set_buffer_async_io(bh); ++ bh = bh->b_this_page; ++ } while (bh != head); ++ ++ /* Stage 2: start the IO */ ++ do { ++ struct buffer_head *next = bh->b_this_page; ++ submit_bh(rw, bh); ++ bh = next; ++ } while (bh != head); ++ return 0; ++} ++ ++/* ++ * We implement to methods: swapping to partitions, and swapping to files ++ * located on partitions. ++ */ ++ ++struct blkdev_swap_data { ++ kdev_t dev; ++}; ++ ++struct test_data { ++ struct file * filp; ++ kdev_t dev; ++}; ++ ++static int is_blkdev_swapping(unsigned int flags, ++ struct file * swapf, ++ void *data) ++{ ++ struct test_data *testdata = (struct test_data *) data; ++ struct file * filp = testdata->filp; ++ kdev_t dev = testdata->dev; ++ ++ /* Only check filp's that don't match the one already opened ++ * for us by sys_swapon(). Otherwise, we will always flag a ++ * busy swap file. ++ */ ++ ++ if (swapf != filp) { ++ if (dev == swapf->f_dentry->d_inode->i_rdev) ++ return 1; ++ } ++ return 0; ++} ++ ++static int blkdev_swap_open(struct file * filp, void **dptr) ++{ ++ int swapfilesize; ++ kdev_t dev; ++ struct blkdev_swap_data *data; ++ int error; ++ struct test_data testdata; ++ ++ MOD_INC_USE_COUNT; ++ ++ if (!S_ISBLK(filp->f_dentry->d_inode->i_mode)) { ++ dprintk(__FUNCTION__": can't handle this swap file: %s\n", ++ swapf->d_name.name); ++ error = 0; /* not for us */ ++ goto bad_swap; ++ } ++ ++ dev = filp->f_dentry->d_inode->i_rdev; ++ set_blocksize(dev, PAGE_SIZE); ++ error = -ENODEV; ++ if (!dev || ++ (blk_size[MAJOR(dev)] && !blk_size[MAJOR(dev)][MINOR(dev)])) { ++ printk("blkdev_swap_open: blkdev weirdness for %s\n", ++ filp->f_dentry->d_name.name); ++ goto bad_swap; ++ } ++ ++ /* Check to make sure that we aren't already swapping. */ ++ error = -EBUSY; ++ testdata.filp = filp; ++ testdata.dev = dev; ++ if (swap_run_test(is_blkdev_swapping, &testdata)) { ++ printk("blkdev_swap_open: already swapping to %s\n", ++ filp->f_dentry->d_name.name); ++ goto bad_swap; ++ } ++ ++ swapfilesize = 0; ++ if (blk_size[MAJOR(dev)]) ++ swapfilesize = blk_size[MAJOR(dev)][MINOR(dev)] ++ >> (PAGE_SHIFT - 10); ++ ++ if ((data = kmalloc(sizeof(*data), GFP_KERNEL)) == NULL) { ++ printk("blkdev_swap_open: can't allocate data for %s\n", ++ filp->f_dentry->d_name.name); ++ error = -ENOMEM; ++ goto bad_swap; ++ } ++ data->dev = dev; ++ *dptr = data; ++ ++ dprintk("blkdev_swap_open: returning %d\n", swapfilesize); ++ return swapfilesize; ++ ++ bad_swap: ++ MOD_DEC_USE_COUNT; ++ return error; /* this swap thing is not for us */ ++} ++ ++static int blkdev_swap_release(struct file * filp, void *data) ++{ ++ dprintk("blkdev_swap_release: releasing swap device %s\n", ++ filp->f_dentry->d_name.name); ++ kfree(data); ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static int blkdev_rw_page(int rw, struct page *page, unsigned long offset, ++ void *ptr) ++{ ++ struct blkdev_swap_data *data = (struct blkdev_swap_data *)ptr; ++ brw_page(rw, page, data->dev, (int *)&offset, PAGE_SIZE); ++ return 1; ++} ++ ++static struct swap_ops blkdev_swap_ops = { ++ blkdev_swap_open, ++ blkdev_swap_release, ++ blkdev_rw_page ++}; ++ ++struct blkdevfile_swap_data { ++ struct inode *swapf; ++}; ++ ++static int is_blkdevfile_swapping(unsigned int flags, ++ struct file * swapf, ++ void * data) ++{ ++ struct file * filp = (struct file *) data; ++ ++ /* Only check filp's that don't match the one already opened ++ * for us by sys_swapon(). Otherwise, we will always flag a ++ * busy swap file. ++ */ ++ ++ if (swapf != filp) { ++ if (filp->f_dentry->d_inode == swapf->f_dentry->d_inode) ++ return 1; ++ } ++ return 0; ++} ++ ++static int blkdevfile_swap_open(struct file *swapf, void **dptr) ++{ ++ int error = 0; ++ int swapfilesize; ++ struct blkdevfile_swap_data *data; ++ ++ MOD_INC_USE_COUNT; ++ ++ /* first check whether this is a regular file located on a local ++ * hard disk ++ */ ++ if (!S_ISREG(swapf->f_dentry->d_inode->i_mode)) { ++ dprintk("blkdevfile_swap_open: " ++ "can't handle this swap file: %s\n", ++ swapf->d_name.name); ++ error = 0; /* not for us */ ++ goto bad_swap; ++ } ++ if (!swapf->f_dentry->d_inode->i_mapping->a_ops->bmap) { ++ dprintk("blkdevfile_swap_open: no bmap for file: %s\n", ++ swapf->d_name.name); ++ error = 0; /* not for us */ ++ goto bad_swap; ++ } ++ ++ if (swap_run_test(is_blkdevfile_swapping, swapf)) { ++ dprintk("blkdevfile_swap_open: already swapping to %s\n", ++ swapf->d_name.name); ++ error = -EBUSY; ++ goto bad_swap; ++ } ++ swapfilesize = swapf->f_dentry->d_inode->i_size >> PAGE_SHIFT; ++ if ((data = kmalloc(sizeof(*data), GFP_KERNEL)) == NULL) { ++ error = -ENOMEM; ++ goto bad_swap; ++ } ++ data->swapf = swapf->f_dentry->d_inode; ++ *dptr = data; ++ return swapfilesize; ++ ++ bad_swap: ++ MOD_DEC_USE_COUNT; ++ return error; ++} ++ ++static int blkdevfile_swap_release(struct file *swapf, void *data) ++{ ++ kfree(data); ++ MOD_DEC_USE_COUNT; ++ return 0; ++} ++ ++static int blkdevfile_rw_page(int rw, struct page *page, unsigned long offset, ++ void *ptr) ++{ ++ struct blkdevfile_swap_data *data = (struct blkdevfile_swap_data *)ptr; ++ struct inode * swapf = data->swapf; ++ int i, j; ++ unsigned int block = offset ++ << (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits); ++ kdev_t dev = swapf->i_dev; ++ int block_size; ++ int zones[PAGE_SIZE/512]; ++ int zones_used; ++ ++ block_size = swapf->i_sb->s_blocksize; ++ for (i=0, j=0; j< PAGE_SIZE ; i++, j += block_size) ++ if (!(zones[i] = bmap(swapf,block++))) { ++ printk("blkdevfile_rw_page: bad swap file\n"); ++ return 0; ++ } ++ zones_used = i; ++ ++ /* block_size == PAGE_SIZE/zones_used */ ++ brw_page(rw, page, dev, zones, block_size); ++ return 1; ++} ++ ++static struct swap_ops blkdevfile_swap_ops = { ++ blkdevfile_swap_open, ++ blkdevfile_swap_release, ++ blkdevfile_rw_page ++ }; ++ ++int __init blkdev_swap_init(void) ++{ ++ (void)register_swap_method(BLKDEV_SWAP_ID, &blkdev_swap_ops); ++ (void)register_swap_method(BLKDEV_FILE_SWAP_ID, &blkdevfile_swap_ops); ++ return 0; ++} ++ ++void __exit blkdev_swap_exit(void) ++{ ++ unregister_swap_method(BLKDEV_SWAP_ID); ++ unregister_swap_method(BLKDEV_FILE_SWAP_ID); ++} ++ ++module_init(blkdev_swap_init) ++module_exit(blkdev_swap_exit) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("Many. Stuffed into a module by cH (Claus-Justus Heine)"); ++MODULE_DESCRIPTION("Swapping to partitions and files on local hard-disks"); +diff -Nurb src/linux/linux.orig/fs/buffer.c src/linux/linux/fs/buffer.c +--- src/linux/linux.orig/fs/buffer.c 2003-07-04 04:12:05.000000000 -0400 ++++ src/linux/linux/fs/buffer.c 2004-05-31 02:21:05.000000000 -0400 +@@ -743,7 +743,7 @@ + bh->b_private = private; + } + +-static void end_buffer_io_async(struct buffer_head * bh, int uptodate) ++void end_buffer_io_async(struct buffer_head * bh, int uptodate) + { + static spinlock_t page_uptodate_lock = SPIN_LOCK_UNLOCKED; + unsigned long flags; +@@ -2344,35 +2344,6 @@ + return err; + } + +-int brw_page(int rw, struct page *page, kdev_t dev, int b[], int size) +-{ +- struct buffer_head *head, *bh; +- +- if (!PageLocked(page)) +- panic("brw_page: page not locked for I/O"); +- +- if (!page->buffers) +- create_empty_buffers(page, dev, size); +- head = bh = page->buffers; +- +- /* Stage 1: lock all the buffers */ +- do { +- lock_buffer(bh); +- bh->b_blocknr = *(b++); +- set_bit(BH_Mapped, &bh->b_state); +- set_buffer_async_io(bh); +- bh = bh->b_this_page; +- } while (bh != head); +- +- /* Stage 2: start the IO */ +- do { +- struct buffer_head *next = bh->b_this_page; +- submit_bh(rw, bh); +- bh = next; +- } while (bh != head); +- return 0; +-} +- + int block_symlink(struct inode *inode, const char *symname, int len) + { + struct address_space *mapping = inode->i_mapping; +diff -Nurb src/linux/linux.orig/fs/nfs/Makefile src/linux/linux/fs/nfs/Makefile +--- src/linux/linux.orig/fs/nfs/Makefile 2003-07-04 04:12:07.000000000 -0400 ++++ src/linux/linux/fs/nfs/Makefile 2004-05-31 02:18:03.000000000 -0400 +@@ -15,6 +15,14 @@ + obj-$(CONFIG_ROOT_NFS) += nfsroot.o mount_clnt.o + obj-$(CONFIG_NFS_V3) += nfs3proc.o nfs3xdr.o + +-obj-m := $(O_TARGET) ++obj-$(CONFIG_SWAP_VIA_NFS) += nfsswap.o ++ifeq ($(CONFIG_SWAP_VIA_NFS),m) ++export-objs := nfs_syms.o ++obj-y += nfs_syms.o ++endif ++ ++ifeq ($(CONFIG_NFS_FS),m) ++obj-m += $(O_TARGET) ++endif + + include $(TOPDIR)/Rules.make +diff -Nurb src/linux/linux.orig/fs/nfs/file.c src/linux/linux/fs/nfs/file.c +--- src/linux/linux.orig/fs/nfs/file.c 2003-07-04 04:12:07.000000000 -0400 ++++ src/linux/linux/fs/nfs/file.c 2004-05-31 02:18:03.000000000 -0400 +@@ -58,11 +58,6 @@ + setattr: nfs_notify_change, + }; + +-/* Hack for future NFS swap support */ +-#ifndef IS_SWAPFILE +-# define IS_SWAPFILE(inode) (0) +-#endif +- + /* + * Flush all dirty pages, and check for write errors. + * +@@ -217,8 +212,6 @@ + inode->i_ino, (unsigned long) count, (unsigned long) *ppos); + + result = -EBUSY; +- if (IS_SWAPFILE(inode)) +- goto out_swapfile; + result = nfs_revalidate_inode(NFS_SERVER(inode), inode); + if (result) + goto out; +@@ -230,10 +223,6 @@ + result = generic_file_write(file, buf, count, ppos); + out: + return result; +- +-out_swapfile: +- printk(KERN_INFO "NFS: attempt to write to active swap file!\n"); +- goto out; + } + + /* +diff -Nurb src/linux/linux.orig/fs/nfs/nfs_syms.c src/linux/linux/fs/nfs/nfs_syms.c +--- src/linux/linux.orig/fs/nfs/nfs_syms.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/fs/nfs/nfs_syms.c 2004-05-31 02:18:03.000000000 -0400 +@@ -0,0 +1,10 @@ ++#include ++#define __NO_VERSION__ ++#include ++#include ++#include ++#include ++ ++EXPORT_SYMBOL(__nfs_refresh_inode); ++EXPORT_SYMBOL(nfs_write_attributes); ++ +diff -Nurb src/linux/linux.orig/fs/nfs/nfsswap.c src/linux/linux/fs/nfs/nfsswap.c +--- src/linux/linux.orig/fs/nfs/nfsswap.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/fs/nfs/nfsswap.c 2004-05-31 02:18:03.000000000 -0400 +@@ -0,0 +1,350 @@ ++/* ++ * Swapping to files located on NFS mounted volumes ++ * Copyright (c) 2000 Claus-Justus Heine ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++#define NFSDBG_FACILITY NFSDBG_SWAP ++ ++#define NFS_SWAP_ID "nfs file" ++ ++/* we cache some values here. In principle, we only need the file. ++ */ ++struct nfs_swap_data { ++ struct file *file; ++ struct inode *inode; ++ struct nfs_server *server; ++ struct socket *socket; ++}; ++ ++/* Nearly a clone of nfs_readpage_sync() in read.c, but "struct page" does not ++ * contain information about the file offset when swapping. So. ++ */ ++static int nfs_read_swap_page(struct page *page, ++ struct nfs_server *server, ++ struct inode *inode, ++ struct file *file) ++{ ++ unsigned int rsize = server->rsize; ++ unsigned int count = PAGE_SIZE; ++ unsigned int offset = 0; /* always at start of page */ ++ int result, eof; ++ struct rpc_cred *cred; ++ struct nfs_fattr fattr; ++ ++ cred = nfs_file_cred(file); ++ ++ do { ++ if (count < rsize) ++ rsize = count; ++ ++ lock_kernel(); ++ result = NFS_PROTO(inode)->read(inode, cred, ++ &fattr, ++ NFS_RPC_SWAPFLAGS, ++ offset, rsize, page, &eof); ++ nfs_refresh_inode(inode, &fattr); ++ unlock_kernel(); ++ ++ /* ++ * Even if we had a partial success we can't mark the page ++ * cache valid. ++ */ ++ if (result < 0) { ++ if (result == -EISDIR) ++ result = -EINVAL; ++ goto io_error; ++ } ++ count -= result; ++ offset += result; ++ if (result < rsize) /* NFSv2ism */ ++ break; ++ } while (count); ++ ++ if (count) { ++ char *kaddr = kmap(page); ++ memset(kaddr + offset, 0, count); ++ kunmap(page); ++ } ++ flush_dcache_page(page); ++ result = 0; ++ ++io_error: ++ return result; ++} ++ ++/* Like nfs_writepage_sync(), but when swapping page->index does not encode ++ * the offset in the swap file alone. ++ * ++ */ ++static int nfs_write_swap_page(struct page *page, ++ struct nfs_server *server, ++ struct inode *inode, ++ struct file *file) ++{ ++ struct rpc_cred *cred; ++ unsigned int wsize = server->wsize; ++ unsigned int count = PAGE_SIZE; ++ unsigned int offset = 0; ++ int result; ++ struct nfs_writeverf verf; ++ struct nfs_fattr fattr; ++ ++ cred = nfs_file_cred(file); ++ ++ do { ++ if (count < wsize) ++ wsize = count; ++ ++ lock_kernel(); ++ result = NFS_PROTO(inode)->write(inode, cred, &fattr, ++ NFS_RW_SWAP|NFS_RW_SYNC, ++ offset, wsize, page, &verf); ++ nfs_write_attributes(inode, &fattr); ++ unlock_kernel(); ++ ++ if (result < 0) { ++ goto io_error; ++ } ++ if (result != wsize) ++ printk("NFS: short write, wsize=%u, result=%d\n", ++ wsize, result); ++ offset += wsize; ++ count -= wsize; ++ /* ++ * If we've extended the file, update the inode ++ * now so we don't invalidate the cache. ++ */ ++ if (offset > inode->i_size) ++ inode->i_size = offset; ++ } while (count); ++ ++ result = 0; ++ ++io_error: ++ ++ return result; ++} ++ ++/* Unluckily (for us) form 2.4.19 -> 2.4.20 the nfs-proc's where ++ * changed and expect now a proper file-mapping page, where index ++ * encodes the offset alone. ++ * ++ * What we do: we save the original value of page->index, initialize ++ * page->index to what the NFS/sun-rpc subsystem expects and restore ++ * the index later. ++ */ ++static int nfs_rw_swap_page(int rw, struct page *page, ++ unsigned long offset, void *dptr) ++{ ++ int error; ++ struct nfs_swap_data *data = dptr; ++ unsigned long alloc_flag = current->flags & PF_MEMALLOC; ++ unsigned long page_index; ++ ++ if (!PageLocked(page)) ++ panic("nfs_rw_swap_page: page not locked for I/O"); ++ ++ /* prevent memory deadlocks */ ++ if (!(current->flags & PF_MEMALLOC)) { ++ dprintk("nfs_rw_swap_page: Setting PF_MEMALLOC\n"); ++ } ++ current->flags |= PF_MEMALLOC; ++ ++ /* now tweak the page->index field ... */ ++ page_index = page->index; ++ page->index = ((loff_t)offset*(loff_t)PAGE_SIZE) >> PAGE_CACHE_SHIFT; ++ ++ if (rw == WRITE) { ++ error = nfs_write_swap_page(page, ++ data->server, ++ data->inode, ++ data->file); ++ } else { ++ error = nfs_read_swap_page(page, ++ data->server, ++ data->inode, ++ data->file); ++ } ++ ++ if (!alloc_flag) { ++ current->flags &= ~PF_MEMALLOC; ++ } ++ ++ /* now restore the page->index field ... */ ++ page->index = page_index; ++ ++ if (error) { ++ /* Must mark the page invalid after I/O error */ ++ SetPageError(page); ++ ClearPageUptodate(page); ++ } else { ++ ClearPageError(page); ++ SetPageUptodate(page); ++ } ++ ++ if (!error) { /* in case of an error rw_swap_page() likes to unlock ++ * itself. ++ */ ++ UnlockPage(page); ++ } ++ ++ return error < 0 ? 0 : 1; ++} ++ ++static int is_nfsfile_swapping(unsigned int flags, ++ struct file * swapf, ++ void * data) ++{ ++ struct file * filp = (struct file *) data; ++ ++ /* Only check filp's that don't match the one already opened ++ * for us by sys_swapon(). Otherwise, we will always flag a ++ * busy swap file. ++ */ ++ ++ if (swapf != filp) { ++ if (filp->f_dentry->d_inode == swapf->f_dentry->d_inode) ++ return 1; ++ } ++ return 0; ++} ++ ++static int nfs_swap_open(struct file *swapf, void **dptr) ++{ ++ int error = 0; ++ int swapfilesize; ++ struct nfs_swap_data *data; ++ int on = 1; ++ mm_segment_t fs; ++ struct inode *inode = swapf->f_dentry->d_inode; ++ ++ MOD_INC_USE_COUNT; ++ ++ if (!S_ISREG(inode->i_mode)) { ++ dprintk("nfs_swap_open: can't handle this swap file: %s\n", ++ swapf->f_dentry->d_name.name); ++ error = 0; /* not for us */ ++ goto bad_swap; ++ } ++ /* determine whether this file really is located on an NFS mounted ++ * volume ++ */ ++ if (!inode->i_sb || inode->i_sb->s_magic != NFS_SUPER_MAGIC) { ++ dprintk("nfs_swap_open: %s is not an NFS file.\n", ++ swapf->f_dentry->d_name.name); ++ error = 0; /* not for us */ ++ goto bad_swap; ++ } ++ ++ if (swap_run_test(is_nfsfile_swapping, swapf)) { ++ dprintk("nfs_swap_open: already swapping to %s\n", ++ swapf->f_dentry->d_name.name); ++ error = -EBUSY; ++ goto bad_swap; ++ } ++ swapfilesize = inode->i_size >> PAGE_SHIFT; ++ if ((data = kmalloc(sizeof(*data), GFP_KERNEL)) == NULL) { ++ error = -ENOMEM; ++ goto bad_swap; ++ } ++ data->file = swapf; ++ data->inode = inode; ++ data->server = NFS_SERVER(inode); ++ data->socket = data->server->client->cl_xprt->sock; ++ ++ /* set socket option SO_SWAPPING */ ++ fs = get_fs(); ++ set_fs(KERNEL_DS); ++ error = sock_setsockopt(data->socket, SOL_SOCKET, SO_SWAPPING, ++ (char *)&on, sizeof(on)); ++ set_fs(fs); ++ if (error) { ++ dprintk("nfs_swap_open: error setting SO_SWAPPING\n"); ++ goto bad_swap_2; ++ } ++ ++ *dptr = data; ++ return swapfilesize; ++ ++ bad_swap_2: ++ kfree(data); ++ bad_swap: ++ MOD_DEC_USE_COUNT; ++ return error; ++} ++ ++static int nfs_swap_release(struct file *swapf, void *dptr) ++{ ++ struct nfs_swap_data *data = (struct nfs_swap_data *)dptr; ++ int off = 0; ++ mm_segment_t fs; ++ int error; ++ ++#if 1 ++ if (swapf != data->file || ++ swapf->f_dentry->d_inode != data->inode || ++ !swapf->f_dentry->d_inode->i_sb || ++ swapf->f_dentry->d_inode->i_sb->s_magic != NFS_SUPER_MAGIC || ++ NFS_SERVER(swapf->f_dentry->d_inode) != data->server || ++ data->socket != data->server->client->cl_xprt->sock) { ++ panic("nfs_swap_release: nfs swap data messed up"); ++ } ++#endif ++ ++ /* remove socket option SO_SWAPPING */ ++ fs = get_fs(); ++ set_fs(KERNEL_DS); ++ error = sock_setsockopt(data->socket, SOL_SOCKET, SO_SWAPPING, ++ (char *)&off, sizeof(off)); ++ set_fs(fs); ++ if (error) { ++ dprintk("nfs_swap_open: error clearing SO_SWAPPING\n"); ++ } ++ kfree(data); ++ MOD_DEC_USE_COUNT; ++ return error; ++} ++ ++static struct swap_ops nfs_swap_ops = { ++ open: nfs_swap_open, ++ release: nfs_swap_release, ++ rw_page: nfs_rw_swap_page ++}; ++ ++int __init nfs_swap_init(void) ++{ ++ (void)register_swap_method(NFS_SWAP_ID, &nfs_swap_ops); ++ return 0; ++} ++ ++void __exit nfs_swap_exit(void) ++{ ++ unregister_swap_method(NFS_SWAP_ID); ++} ++ ++module_init(nfs_swap_init) ++module_exit(nfs_swap_exit) ++ ++MODULE_LICENSE("GPL"); ++MODULE_AUTHOR("(c) 1996-2002 cH (Claus-Justus Heine)"); ++MODULE_DESCRIPTION("Swapping to files located on volumes mounted via NFS"); +diff -Nurb src/linux/linux.orig/fs/nfs/read.c src/linux/linux/fs/nfs/read.c +--- src/linux/linux.orig/fs/nfs/read.c 2003-07-04 04:12:08.000000000 -0400 ++++ src/linux/linux/fs/nfs/read.c 2004-05-31 02:18:03.000000000 -0400 +@@ -50,11 +50,6 @@ + */ + static void nfs_readpage_result(struct rpc_task *task); + +-/* Hack for future NFS swap support */ +-#ifndef IS_SWAPFILE +-# define IS_SWAPFILE(inode) (0) +-#endif +- + static kmem_cache_t *nfs_rdata_cachep; + + static __inline__ struct nfs_read_data *nfs_readdata_alloc(void) +@@ -92,7 +87,6 @@ + int rsize = NFS_SERVER(inode)->rsize; + int result; + int count = PAGE_CACHE_SIZE; +- int flags = IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0; + int eof; + + dprintk("NFS: nfs_readpage_sync(%p)\n", page); +@@ -114,7 +108,7 @@ + offset, rsize, page); + + lock_kernel(); +- result = NFS_PROTO(inode)->read(inode, cred, &fattr, flags, ++ result = NFS_PROTO(inode)->read(inode, cred, &fattr, 0, + offset, rsize, page, &eof); + nfs_refresh_inode(inode, &fattr); + unlock_kernel(); +@@ -246,7 +240,7 @@ + task = &data->task; + + /* N.B. Do we need to test? Never called for swapfile inode */ +- flags = RPC_TASK_ASYNC | (IS_SWAPFILE(inode)? NFS_RPC_SWAPFLAGS : 0); ++ flags = RPC_TASK_ASYNC; + + nfs_read_rpcsetup(head, data); + +@@ -476,8 +470,6 @@ + } + + error = nfs_readpage_sync(file, inode, page); +- if (error < 0 && IS_SWAPFILE(inode)) +- printk("Aiee.. nfs swap-in of page failed!\n"); + out: + return error; + +diff -Nurb src/linux/linux.orig/fs/nfs/write.c src/linux/linux/fs/nfs/write.c +--- src/linux/linux.orig/fs/nfs/write.c 2003-07-04 04:12:08.000000000 -0400 ++++ src/linux/linux/fs/nfs/write.c 2004-05-31 02:20:47.000000000 -0400 +@@ -3,7 +3,6 @@ + #include + #include + #include +-#include + #include + #include + +@@ -46,11 +45,6 @@ + static void nfs_commit_done(struct rpc_task *); + #endif + +-/* Hack for future NFS swap support */ +-#ifndef IS_SWAPFILE +-# define IS_SWAPFILE(inode) (0) +-#endif +- + static kmem_cache_t *nfs_wdata_cachep; + + static __inline__ struct nfs_write_data *nfs_writedata_alloc(void) +@@ -82,7 +76,7 @@ + * For the moment, we just call nfs_refresh_inode(). + */ + static __inline__ int +-nfs_write_attributes(struct inode *inode, struct nfs_fattr *fattr) ++__nfs_write_attributes(struct inode *inode, struct nfs_fattr *fattr) + { + if ((fattr->valid & NFS_ATTR_FATTR) && !(fattr->valid & NFS_ATTR_WCC)) { + fattr->pre_size = NFS_CACHE_ISIZE(inode); +@@ -93,6 +87,11 @@ + return nfs_refresh_inode(inode, fattr); + } + ++int nfs_write_attributes(struct inode *inode, struct nfs_fattr *fattr) ++{ ++ return __nfs_write_attributes(inode, fattr); ++} ++ + /* + * Write a page synchronously. + * Offset is the data offset within the page. +@@ -104,8 +103,7 @@ + struct rpc_cred *cred = NULL; + loff_t base; + unsigned int wsize = NFS_SERVER(inode)->wsize; +- int result, refresh = 0, written = 0, flags; +- u8 *buffer; ++ int result, refresh = 0, written = 0; + struct nfs_fattr fattr; + struct nfs_writeverf verf; + +@@ -121,15 +119,14 @@ + + base = page_offset(page) + offset; + +- flags = ((IS_SWAPFILE(inode)) ? NFS_RW_SWAP : 0) | NFS_RW_SYNC; +- + do { +- if (count < wsize && !IS_SWAPFILE(inode)) ++ if (count < wsize) + wsize = count; + +- result = NFS_PROTO(inode)->write(inode, cred, &fattr, flags, ++ result = NFS_PROTO(inode)->write(inode, cred, &fattr, ++ NFS_RW_SYNC, + offset, wsize, page, &verf); +- nfs_write_attributes(inode, &fattr); ++ __nfs_write_attributes(inode, &fattr); + + if (result < 0) { + /* Must mark the page invalid after I/O error */ +@@ -140,7 +137,6 @@ + printk("NFS: short write, wsize=%u, result=%d\n", + wsize, result); + refresh = 1; +- buffer += wsize; + base += wsize; + offset += wsize; + written += wsize; +@@ -979,7 +975,7 @@ + } + #endif + +- nfs_write_attributes(inode, resp->fattr); ++ __nfs_write_attributes(inode, resp->fattr); + while (!list_empty(&data->pages)) { + req = nfs_list_entry(data->pages.next); + nfs_list_remove_request(req); +@@ -1133,7 +1129,7 @@ + if (nfs_async_handle_jukebox(task)) + return; + +- nfs_write_attributes(inode, resp->fattr); ++ __nfs_write_attributes(inode, resp->fattr); + while (!list_empty(&data->pages)) { + req = nfs_list_entry(data->pages.next); + nfs_list_remove_request(req); +diff -Nurb src/linux/linux.orig/include/linux/fs.h src/linux/linux/include/linux/fs.h +--- src/linux/linux.orig/include/linux/fs.h 2004-05-31 02:06:19.000000000 -0400 ++++ src/linux/linux/include/linux/fs.h 2004-05-31 02:18:03.000000000 -0400 +@@ -1500,6 +1500,10 @@ + extern int inode_change_ok(struct inode *, struct iattr *); + extern int inode_setattr(struct inode *, struct iattr *); + ++/* for swapping to block devices */ ++void create_empty_buffers(struct page *page, kdev_t dev, unsigned long blocksize); ++void end_buffer_io_async(struct buffer_head * bh, int uptodate); ++ + /* + * Common dentry functions for inclusion in the VFS + * or in other stackable file systems. Some of these +diff -Nurb src/linux/linux.orig/include/linux/nfs_fs.h src/linux/linux/include/linux/nfs_fs.h +--- src/linux/linux.orig/include/linux/nfs_fs.h 2004-05-31 02:06:28.000000000 -0400 ++++ src/linux/linux/include/linux/nfs_fs.h 2004-05-31 02:18:03.000000000 -0400 +@@ -40,8 +40,8 @@ + */ + #define NFS_MAX_DIRCACHE 16 + +-#define NFS_MAX_FILE_IO_BUFFER_SIZE 32768 +-#define NFS_DEF_FILE_IO_BUFFER_SIZE 4096 ++#define NFS_MAX_FILE_IO_BUFFER_SIZE (8*PAGE_SIZE) ++#define NFS_DEF_FILE_IO_BUFFER_SIZE PAGE_SIZE + + /* + * The upper limit on timeouts for the exponential backoff algorithm. +@@ -205,6 +205,8 @@ + extern int nfs_writepage(struct page *); + extern int nfs_flush_incompatible(struct file *file, struct page *page); + extern int nfs_updatepage(struct file *, struct page *, unsigned int, unsigned int); ++extern int nfs_write_attributes(struct inode *inode, struct nfs_fattr *fattr); ++ + /* + * Try to write back everything synchronously (but check the + * return value!) +@@ -375,6 +377,7 @@ + #define NFSDBG_XDR 0x0020 + #define NFSDBG_FILE 0x0040 + #define NFSDBG_ROOT 0x0080 ++#define NFSDBG_SWAP 0x0100 + #define NFSDBG_ALL 0xFFFF + + #ifdef __KERNEL__ +diff -Nurb src/linux/linux.orig/include/linux/slab.h src/linux/linux/include/linux/slab.h +--- src/linux/linux.orig/include/linux/slab.h 2004-05-31 02:06:19.000000000 -0400 ++++ src/linux/linux/include/linux/slab.h 2004-05-31 02:18:03.000000000 -0400 +@@ -39,6 +39,7 @@ + #define SLAB_HWCACHE_ALIGN 0x00002000UL /* align objs on a h/w cache lines */ + #define SLAB_CACHE_DMA 0x00004000UL /* use GFP_DMA memory */ + #define SLAB_MUST_HWCACHE_ALIGN 0x00008000UL /* force alignment */ ++#define SLAB_LOW_GFP_ORDER 0x00010000UL /* use as low a gfp order as possible */ + + /* flags passed to a constructor func */ + #define SLAB_CTOR_CONSTRUCTOR 0x001UL /* if not set, then deconstructor */ +diff -Nurb src/linux/linux.orig/include/linux/swap.h src/linux/linux/include/linux/swap.h +--- src/linux/linux.orig/include/linux/swap.h 2004-05-31 02:06:19.000000000 -0400 ++++ src/linux/linux/include/linux/swap.h 2004-05-31 02:18:03.000000000 -0400 +@@ -58,15 +58,29 @@ + #define SWAP_MAP_MAX 0x7fff + #define SWAP_MAP_BAD 0x8000 + ++struct swap_ops { ++ int (*open)(struct file *swapf, void **data); ++ int (*release)(struct file *swapf, void *data); ++ int (*rw_page)(int rw, ++ struct page *page, unsigned long offset, void *data); ++}; ++ ++struct swap_method { ++ struct swap_method *next; ++ char * name; ++ struct swap_ops *ops; ++ int use_count; ++}; ++ + /* + * The in-memory structure used to track swap areas. + */ + struct swap_info_struct { + unsigned int flags; +- kdev_t swap_device; ++ struct file *swap_file; ++ struct swap_method *method; ++ void *data; + spinlock_t sdev_lock; +- struct dentry * swap_file; +- struct vfsmount *swap_vfsmnt; + unsigned short * swap_map; + unsigned int lowest_bit; + unsigned int highest_bit; +@@ -141,11 +155,15 @@ + extern int total_swap_pages; + extern unsigned int nr_swapfiles; + extern struct swap_info_struct swap_info[]; +-extern int is_swap_partition(kdev_t); ++extern int register_swap_method(char *name, struct swap_ops *ops); ++extern int unregister_swap_method(char *name); ++extern int swap_run_test(int (*test_fct)(unsigned int flags, ++ struct file *swap_file, ++ void *testdata), void *testdata); + extern void si_swapinfo(struct sysinfo *); + extern swp_entry_t get_swap_page(void); +-extern void get_swaphandle_info(swp_entry_t, unsigned long *, kdev_t *, +- struct inode **); ++struct swap_method *get_swaphandle_info(swp_entry_t entry, ++ unsigned long *offset, void **data); + extern int swap_duplicate(swp_entry_t); + extern int swap_count(struct page *); + extern int valid_swaphandles(swp_entry_t, unsigned long *); +diff -Nurb src/linux/linux.orig/include/net/netswapping.h src/linux/linux/include/net/netswapping.h +--- src/linux/linux.orig/include/net/netswapping.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/net/netswapping.h 2004-05-31 02:18:03.000000000 -0400 +@@ -0,0 +1,47 @@ ++#ifndef _LINUX_NETSWAPPING_H ++#define _LINUX_NETSWAPPING_H ++ ++#include ++#include ++ ++/* It is a mess. Socket options are defined in asm-ARCH/socket.h */ ++ ++#define SO_SWAPPING 0x00100000 /* hopefully not used by anybody else */ ++ ++#ifdef __KERNEL__ ++ ++#define CTL_NETSWAP 0x00100000 ++ ++enum { ++ NET_SWAP_DROPPED = 1, ++ NET_SWAP_DROP_THRESHOLD = 2, ++ NET_SWAP_SOCK_COUNT = 3 ++}; ++ ++extern unsigned int netswap_free_pages_min; ++extern int netswap_sock_count; ++extern unsigned int netswap_dropped; ++ ++/* this is "#defined" and not inline because sock.h includes us, but we need ++ * the "struct sock" definition. ++ */ ++#define netswap_low_memory(sk, skb) \ ++({ \ ++ int _ret = 0; \ ++ \ ++ if (netswap_sock_count > 0 && /* anybody swapping via network? */ \ ++ !(sk)->swapping && /* but we are not needed for swapping */ \ ++ nr_free_pages() < netswap_free_pages_min) { /* so drop us */ \ ++ printk("netswap_low_memory: " \ ++ "dropping skb 0x%p@0x%p\n", skb, sk); \ ++ netswap_dropped ++; \ ++ _ret = 1; \ ++ } \ ++ _ret; \ ++}) ++ ++extern int __init netswap_init(void); ++ ++#endif ++ ++#endif +diff -Nurb src/linux/linux.orig/include/net/sock.h src/linux/linux/include/net/sock.h +--- src/linux/linux.orig/include/net/sock.h 2004-05-31 02:07:17.000000000 -0400 ++++ src/linux/linux/include/net/sock.h 2004-05-31 02:18:03.000000000 -0400 +@@ -103,6 +103,10 @@ + #include + #endif + ++#ifdef CONFIG_NETSWAP ++#include ++#endif ++ + #include + #include + +@@ -536,6 +540,12 @@ + no_check, + broadcast, + bsdism; ++#ifdef CONFIG_NETSWAP ++ /* Increased by SO_SWAPPING with arg != 0, decreased by ++ * SO_SWAPPING with arg 0 ++ */ ++ int swapping; ++#endif + unsigned char debug; + unsigned char rcvtstamp; + unsigned char use_write_queue; +@@ -1165,6 +1175,11 @@ + return err; /* Toss packet */ + } + #endif /* CONFIG_FILTER */ ++#ifdef CONFIG_NETSWAP ++ /* an inline function defined in net/netswapping.h */ ++ if (netswap_low_memory(sk, skb)) ++ return -ENOMEM; ++#endif /* CONFIG_NETSWAP */ + + skb->dev = NULL; + skb_set_owner_r(skb, sk); +diff -Nurb src/linux/linux.orig/kernel/ksyms.c src/linux/linux/kernel/ksyms.c +--- src/linux/linux.orig/kernel/ksyms.c 2004-05-31 02:02:43.000000000 -0400 ++++ src/linux/linux/kernel/ksyms.c 2004-05-31 02:18:03.000000000 -0400 +@@ -41,6 +41,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -127,6 +128,11 @@ + EXPORT_SYMBOL(kmap_prot); + EXPORT_SYMBOL(kmap_pte); + #endif ++EXPORT_SYMBOL(nr_free_pages); ++/* EXPORT_SYMBOL(freepages); */ ++EXPORT_SYMBOL(register_swap_method); ++EXPORT_SYMBOL(unregister_swap_method); ++EXPORT_SYMBOL(swap_run_test); + + /* filesystem internal functions */ + EXPORT_SYMBOL(def_blk_fops); +@@ -531,7 +537,7 @@ + EXPORT_SYMBOL(make_bad_inode); + EXPORT_SYMBOL(is_bad_inode); + EXPORT_SYMBOL(event); +-EXPORT_SYMBOL(brw_page); ++EXPORT_SYMBOL(end_buffer_io_async); + EXPORT_SYMBOL(__inode_dir_notify); + + #ifdef CONFIG_UID16 +diff -Nurb src/linux/linux.orig/mm/page_io.c src/linux/linux/mm/page_io.c +--- src/linux/linux.orig/mm/page_io.c 2003-07-04 04:12:29.000000000 -0400 ++++ src/linux/linux/mm/page_io.c 2004-05-31 02:18:03.000000000 -0400 +@@ -36,11 +36,8 @@ + static int rw_swap_page_base(int rw, swp_entry_t entry, struct page *page) + { + unsigned long offset; +- int zones[PAGE_SIZE/512]; +- int zones_used; +- kdev_t dev = 0; +- int block_size; +- struct inode *swapf = 0; ++ struct swap_method *method; ++ void *data; + + if (rw == READ) { + ClearPageUptodate(page); +@@ -48,30 +45,11 @@ + } else + kstat.pswpout++; + +- get_swaphandle_info(entry, &offset, &dev, &swapf); +- if (dev) { +- zones[0] = offset; +- zones_used = 1; +- block_size = PAGE_SIZE; +- } else if (swapf) { +- int i, j; +- unsigned int block = offset +- << (PAGE_SHIFT - swapf->i_sb->s_blocksize_bits); +- +- block_size = swapf->i_sb->s_blocksize; +- for (i=0, j=0; j< PAGE_SIZE ; i++, j += block_size) +- if (!(zones[i] = bmap(swapf,block++))) { +- printk("rw_swap_page: bad swap file\n"); +- return 0; +- } +- zones_used = i; +- dev = swapf->i_dev; +- } else { ++ method = get_swaphandle_info(entry, &offset, &data); ++ if (!method || !method->ops->rw_page(rw, page, offset, data)) { + return 0; + } + +- /* block_size == PAGE_SIZE/zones_used */ +- brw_page(rw, page, dev, zones, block_size); + return 1; + } + +diff -Nurb src/linux/linux.orig/mm/slab.c src/linux/linux/mm/slab.c +--- src/linux/linux.orig/mm/slab.c 2003-07-04 04:12:29.000000000 -0400 ++++ src/linux/linux/mm/slab.c 2004-05-31 02:18:03.000000000 -0400 +@@ -111,10 +111,12 @@ + # define CREATE_MASK (SLAB_DEBUG_INITIAL | SLAB_RED_ZONE | \ + SLAB_POISON | SLAB_HWCACHE_ALIGN | \ + SLAB_NO_REAP | SLAB_CACHE_DMA | \ +- SLAB_MUST_HWCACHE_ALIGN) ++ SLAB_MUST_HWCACHE_ALIGN | \ ++ SLAB_LOW_GFP_ORDER) + #else + # define CREATE_MASK (SLAB_HWCACHE_ALIGN | SLAB_NO_REAP | \ +- SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN) ++ SLAB_CACHE_DMA | SLAB_MUST_HWCACHE_ALIGN | \ ++ SLAB_LOW_GFP_ORDER) + #endif + + /* +@@ -247,8 +249,13 @@ + }; + + /* internal c_flags */ +-#define CFLGS_OFF_SLAB 0x010000UL /* slab management in own cache */ +-#define CFLGS_OPTIMIZE 0x020000UL /* optimized slab lookup */ ++#define CFLGS_OFF_SLAB 0x020000UL /* slab management in own cache */ ++#define CFLGS_OPTIMIZE 0x040000UL /* optimized slab lookup */ ++#define CFLGS_MASK (CFLGS_OFF_SLAB | CFLGS_OPTIMIZE) ++ ++#if (CFLGS_MASK & CREATE_MASK) ++# error BUG: internal and external SLAB flags overlap ++#endif + + /* c_dflags (dynamic flags). Need to hold the spinlock to access this member */ + #define DFLGS_GROWN 0x000001UL /* don't reap a recently grown */ +@@ -452,7 +459,12 @@ + snprintf(name, sizeof(name), "size-%Zd",sizes->cs_size); + if (!(sizes->cs_cachep = + kmem_cache_create(name, sizes->cs_size, +- 0, SLAB_HWCACHE_ALIGN, NULL, NULL))) { ++ 0, ++#if CONFIG_NETSWAP ++ SLAB_LOW_GFP_ORDER| /* sorry */ ++#endif ++ SLAB_HWCACHE_ALIGN, ++ NULL, NULL))) { + BUG(); + } + +@@ -731,6 +743,8 @@ + break; + if (!cachep->num) + goto next; ++ if (cachep->gfporder == 0 && (flags & SLAB_LOW_GFP_ORDER)) ++ break; + if (flags & CFLGS_OFF_SLAB && cachep->num > offslab_limit) { + /* Oops, this num of objs will cause problems. */ + cachep->gfporder--; +diff -Nurb src/linux/linux.orig/mm/swapfile.c src/linux/linux/mm/swapfile.c +--- src/linux/linux.orig/mm/swapfile.c 2003-07-04 04:12:29.000000000 -0400 ++++ src/linux/linux/mm/swapfile.c 2004-05-31 02:18:03.000000000 -0400 +@@ -11,12 +11,17 @@ + #include + #include + #include /* for blk_size */ ++#include + #include + #include + #include + + #include + ++#ifdef CONFIG_KMOD ++#include ++#endif ++ + spinlock_t swaplock = SPIN_LOCK_UNLOCKED; + unsigned int nr_swapfiles; + int total_swap_pages; +@@ -31,8 +36,78 @@ + + struct swap_info_struct swap_info[MAX_SWAPFILES]; + ++static struct swap_method *swap_methods = NULL; ++ + #define SWAPFILE_CLUSTER 256 + ++int register_swap_method(char *name, struct swap_ops *ops) ++{ ++ struct swap_method *pos; ++ struct swap_method *new; ++ int result = 0; ++ ++ lock_kernel(); ++ ++ for (pos = swap_methods; pos; pos = pos->next) { ++ if (strcmp(pos->name, name) == 0) { ++ printk(KERN_ERR "register_swap_method: " ++ "method %s already registered\n", name); ++ result = -EBUSY; ++ goto out; ++ } ++ } ++ ++ if (!(new = kmalloc(sizeof(*new), GFP_KERNEL))) { ++ printk(KERN_ERR "register_swap_method: " ++ "no memory for new method \"%s\"\n", name); ++ result = -ENOMEM; ++ goto out; ++ } ++ ++ new->name = name; ++ new->ops = ops; ++ new->use_count = 0; ++ ++ /* ok, insert at top of list */ ++ printk("register_swap_method: method %s\n", name); ++ new->next = swap_methods; ++ swap_methods = new; ++ out: ++ unlock_kernel(); ++ return result; ++} ++ ++int unregister_swap_method(char *name) ++{ ++ struct swap_method **method, *next; ++ int result = 0; ++ ++ lock_kernel(); ++ ++ for (method = &swap_methods; *method; method = &(*method)->next) { ++ if (strcmp((*method)->name, name) == 0) { ++ if ((*method)->use_count > 0) { ++ printk(KERN_ERR "unregister_swap_method: " ++ "method \"%s\" is in use\n", name); ++ result = -EBUSY; ++ goto out; ++ } ++ ++ next = (*method)->next; ++ kfree(*method); ++ *method = next; ++ printk("unregister_swap_method: method %s\n", name); ++ goto out; ++ } ++ } ++ /* not found */ ++ printk("unregister_swap_method: no such method %s\n", name); ++ result = -ENOENT; ++ out: ++ unlock_kernel(); ++ return result; ++} ++ + static inline int scan_swap_map(struct swap_info_struct *si) + { + unsigned long offset; +@@ -711,13 +786,14 @@ + struct nameidata nd; + int i, type, prev; + int err; ++ struct file *swap_file; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + + err = user_path_walk(specialfile, &nd); + if (err) +- goto out; ++ return err; + + lock_kernel(); + prev = -1; +@@ -725,15 +801,20 @@ + for (type = swap_list.head; type >= 0; type = swap_info[type].next) { + p = swap_info + type; + if ((p->flags & SWP_WRITEOK) == SWP_WRITEOK) { +- if (p->swap_file == nd.dentry) ++ if (p->swap_file && ++ p->swap_file->f_dentry == nd.dentry) + break; + } + prev = type; + } + err = -EINVAL; ++ /* p->swap_file contains all needed info, no need to keep nd, so ++ * release it now. ++ */ ++ path_release(&nd); + if (type < 0) { + swap_list_unlock(); +- goto out_dput; ++ goto out; + } + + if (prev < 0) { +@@ -767,32 +848,30 @@ + total_swap_pages += p->pages; + p->flags = SWP_WRITEOK; + swap_list_unlock(); +- goto out_dput; ++ goto out; + } +- if (p->swap_device) +- blkdev_put(p->swap_file->d_inode->i_bdev, BDEV_SWAP); +- path_release(&nd); + ++ if (p->method->ops->release) ++ p->method->ops->release(p->swap_file, p->data); + swap_list_lock(); + swap_device_lock(p); +- nd.mnt = p->swap_vfsmnt; +- nd.dentry = p->swap_file; +- p->swap_vfsmnt = NULL; ++ p->method->use_count --; ++ p->method = NULL; ++ p->data = NULL; ++ swap_file = p->swap_file; + p->swap_file = NULL; +- p->swap_device = 0; + p->max = 0; + swap_map = p->swap_map; + p->swap_map = NULL; + p->flags = 0; + swap_device_unlock(p); + swap_list_unlock(); ++ filp_close(swap_file, NULL); + vfree(swap_map); + err = 0; + +-out_dput: +- unlock_kernel(); +- path_release(&nd); + out: ++ unlock_kernel(); + return err; + } + +@@ -805,18 +884,17 @@ + if (!page) + return -ENOMEM; + +- len += sprintf(buf, "Filename\t\t\tType\t\tSize\tUsed\tPriority\n"); ++ len += sprintf(buf, "%-32s%-16s%-8s%-8sPriority\n", ++ "Filename", "Type", "Size", "Used"); + for (i = 0 ; i < nr_swapfiles ; i++, ptr++) { + if ((ptr->flags & SWP_USED) && ptr->swap_map) { +- char * path = d_path(ptr->swap_file, ptr->swap_vfsmnt, ++ char * path = d_path(ptr->swap_file->f_dentry, ++ ptr->swap_file->f_vfsmnt, + page, PAGE_SIZE); + + len += sprintf(buf + len, "%-31s ", path); + +- if (!ptr->swap_device) +- len += sprintf(buf + len, "file\t\t"); +- else +- len += sprintf(buf + len, "partition\t"); ++ len += sprintf(buf + len, "%-15s ", ptr->method->name); + + usedswap = 0; + for (j = 0; j < ptr->max; ++j) +@@ -827,7 +905,7 @@ + default: + usedswap++; + } +- len += sprintf(buf + len, "%d\t%d\t%d\n", ptr->pages << (PAGE_SHIFT - 10), ++ len += sprintf(buf + len, "%-8d%-8d%d\n", ptr->pages << (PAGE_SHIFT - 10), + usedswap << (PAGE_SHIFT - 10), ptr->prio); + } + } +@@ -835,18 +913,55 @@ + return len; + } + +-int is_swap_partition(kdev_t dev) { ++/* apply a test function to all active swap objects. E.g. for checking ++ * whether a partition is used for swapping ++ */ ++int swap_run_test(int (*test_fct)(unsigned int flags, ++ struct file * swap_file, ++ void *testdata), void *testdata) ++{ + struct swap_info_struct *ptr = swap_info; + int i; + + for (i = 0 ; i < nr_swapfiles ; i++, ptr++) { +- if (ptr->flags & SWP_USED) +- if (ptr->swap_device == dev) ++ if (ptr->swap_file && ++ test_fct(ptr->flags, ptr->swap_file, testdata)) + return 1; + } + return 0; + } + ++/* Walk through the list of known swap method until somebody wants to ++ * handle this file. Pick the first one which claims to be able to ++ * swap to this kind of file. ++ * ++ * return value: < 0: error, 0: not found, > 0: swapfilesize ++ */ ++int find_swap_method(struct file *swap_file, ++ struct swap_info_struct *p) ++{ ++ int swapfilesize = 0; ++ struct swap_method *method; ++ ++ p->method = NULL; ++ for (method = swap_methods; method; method = method->next) { ++ swapfilesize = method->ops->open(swap_file, &p->data); ++ if (swapfilesize == 0) { ++ continue; ++ } ++ if (swapfilesize > 0) { ++ p->method = method; ++ p->method->use_count ++; ++ p->swap_file = swap_file; ++ break; ++ } ++ if (swapfilesize < 0) { ++ break; ++ } ++ } ++ return swapfilesize; ++} ++ + /* + * Written 01/25/92 by Simmule Turner, heavily changed by Linus. + * +@@ -855,8 +970,6 @@ + asmlinkage long sys_swapon(const char * specialfile, int swap_flags) + { + struct swap_info_struct * p; +- struct nameidata nd; +- struct inode * swap_inode; + unsigned int type; + int i, j, prev; + int error; +@@ -866,8 +979,9 @@ + int nr_good_pages = 0; + unsigned long maxpages = 1; + int swapfilesize; +- struct block_device *bdev = NULL; + unsigned short *swap_map; ++ char * tmp_specialfile; ++ struct file *swap_file; + + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; +@@ -886,8 +1000,7 @@ + nr_swapfiles = type+1; + p->flags = SWP_USED; + p->swap_file = NULL; +- p->swap_vfsmnt = NULL; +- p->swap_device = 0; ++ p->method = NULL; + p->swap_map = NULL; + p->lowest_bit = 0; + p->highest_bit = 0; +@@ -901,53 +1014,56 @@ + p->prio = --least_priority; + } + swap_list_unlock(); +- error = user_path_walk(specialfile, &nd); +- if (error) ++ ++ /* Open the swap using filp_open. Bail out on any errors. */ ++ tmp_specialfile = getname(specialfile); ++ if (IS_ERR(tmp_specialfile)) { ++ error = PTR_ERR(tmp_specialfile); + goto bad_swap_2; ++ } ++ p->swap_file = filp_open(tmp_specialfile, O_RDWR, 0600); ++ putname(tmp_specialfile); ++ if (IS_ERR(p->swap_file)) { ++ error = PTR_ERR(p->swap_file); ++ goto bad_swap_1; ++ } + +- p->swap_file = nd.dentry; +- p->swap_vfsmnt = nd.mnt; +- swap_inode = nd.dentry->d_inode; + error = -EINVAL; + +- if (S_ISBLK(swap_inode->i_mode)) { +- kdev_t dev = swap_inode->i_rdev; +- struct block_device_operations *bdops; +- devfs_handle_t de; +- +- p->swap_device = dev; +- set_blocksize(dev, PAGE_SIZE); +- +- bd_acquire(swap_inode); +- bdev = swap_inode->i_bdev; +- de = devfs_get_handle_from_inode(swap_inode); +- bdops = devfs_get_ops(de); /* Increments module use count */ +- if (bdops) bdev->bd_op = bdops; +- +- error = blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_SWAP); +- devfs_put_ops(de);/*Decrement module use count now we're safe*/ +- if (error) +- goto bad_swap_2; +- set_blocksize(dev, PAGE_SIZE); +- error = -ENODEV; +- if (!dev || (blk_size[MAJOR(dev)] && +- !blk_size[MAJOR(dev)][MINOR(dev)])) +- goto bad_swap; +- swapfilesize = 0; +- if (blk_size[MAJOR(dev)]) +- swapfilesize = blk_size[MAJOR(dev)][MINOR(dev)] +- >> (PAGE_SHIFT - 10); +- } else if (S_ISREG(swap_inode->i_mode)) +- swapfilesize = swap_inode->i_size >> PAGE_SHIFT; +- else +- goto bad_swap; ++ swapfilesize = find_swap_method(p->swap_file, p); ++ if (swapfilesize < 0) { ++ error = swapfilesize; ++ goto bad_swap_1; ++ } ++#ifdef CONFIG_KMOD ++ if (swapfilesize == 0) { ++ (void)request_module("swapfile-mod"); ++ ++ swapfilesize = find_swap_method(p->swap_file, p); ++ if (swapfilesize < 0) { ++ error = swapfilesize; ++ goto bad_swap_1; ++ } ++ } ++#endif ++ if (swapfilesize == 0) { ++ printk("Don't know how to swap to this kind of file\n"); ++ goto bad_swap_1; /* free swap map */ ++ } ++ ++ /* After this point, the swap-file has been opened by the swap ++ * method. We must make sure to use the bad_swap label for any ++ * errors. ++ */ + + error = -EBUSY; + for (i = 0 ; i < nr_swapfiles ; i++) { + struct swap_info_struct *q = &swap_info[i]; + if (i == type || !q->swap_file) + continue; +- if (swap_inode->i_mapping == q->swap_file->d_inode->i_mapping) ++ if (p->swap_file->f_dentry->d_inode->i_mapping ++ == ++ q->swap_file->f_dentry->d_inode->i_mapping) + goto bad_swap; + } + +@@ -1083,17 +1199,27 @@ + swap_list_unlock(); + error = 0; + goto out; ++ + bad_swap: +- if (bdev) +- blkdev_put(bdev, BDEV_SWAP); ++ if (p->method->ops->release) ++ p->method->ops->release(p->swap_file, p->data); ++ swap_list_lock(); ++ p->method->use_count --; ++ p->method = NULL; ++ p->data = NULL; ++ swap_list_unlock(); ++ ++bad_swap_1: ++ swap_list_lock(); ++ swap_file = p->swap_file; ++ p->swap_file = NULL; ++ swap_list_unlock(); ++ filp_close(swap_file, NULL); ++ + bad_swap_2: ++ + swap_list_lock(); + swap_map = p->swap_map; +- nd.mnt = p->swap_vfsmnt; +- nd.dentry = p->swap_file; +- p->swap_device = 0; +- p->swap_file = NULL; +- p->swap_vfsmnt = NULL; + p->swap_map = NULL; + p->flags = 0; + if (!(swap_flags & SWAP_FLAG_PREFER)) +@@ -1101,7 +1227,7 @@ + swap_list_unlock(); + if (swap_map) + vfree(swap_map); +- path_release(&nd); ++ + out: + if (swap_header) + free_page((long) swap_header); +@@ -1217,8 +1343,8 @@ + /* + * Prior swap_duplicate protects against swap device deletion. + */ +-void get_swaphandle_info(swp_entry_t entry, unsigned long *offset, +- kdev_t *dev, struct inode **swapf) ++struct swap_method *get_swaphandle_info(swp_entry_t entry, ++ unsigned long *offset, void **data) + { + unsigned long type; + struct swap_info_struct *p; +@@ -1226,32 +1352,26 @@ + type = SWP_TYPE(entry); + if (type >= nr_swapfiles) { + printk(KERN_ERR "rw_swap_page: %s%08lx\n", Bad_file, entry.val); +- return; ++ return NULL; + } + + p = &swap_info[type]; + *offset = SWP_OFFSET(entry); + if (*offset >= p->max && *offset != 0) { + printk(KERN_ERR "rw_swap_page: %s%08lx\n", Bad_offset, entry.val); +- return; ++ return NULL; + } + if (p->swap_map && !p->swap_map[*offset]) { + printk(KERN_ERR "rw_swap_page: %s%08lx\n", Unused_offset, entry.val); +- return; ++ return NULL; + } + if (!(p->flags & SWP_USED)) { + printk(KERN_ERR "rw_swap_page: %s%08lx\n", Unused_file, entry.val); +- return; ++ return NULL; + } + +- if (p->swap_device) { +- *dev = p->swap_device; +- } else if (p->swap_file) { +- *swapf = p->swap_file->d_inode; +- } else { +- printk(KERN_ERR "rw_swap_page: no swap file or device\n"); +- } +- return; ++ *data = p->data; ++ return p->method; + } + + /* +diff -Nurb src/linux/linux.orig/net/Config.in src/linux/linux/net/Config.in +--- src/linux/linux.orig/net/Config.in 2003-07-04 04:12:29.000000000 -0400 ++++ src/linux/linux/net/Config.in 2004-05-31 02:18:03.000000000 -0400 +@@ -16,6 +16,9 @@ + fi + bool 'Socket Filtering' CONFIG_FILTER + tristate 'Unix domain sockets' CONFIG_UNIX ++if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then ++ bool 'Swapping via network sockets (EXPERIMENTAL)' CONFIG_NETSWAP ++fi + bool 'TCP/IP networking' CONFIG_INET + if [ "$CONFIG_INET" = "y" ]; then + source net/ipv4/Config.in +diff -Nurb src/linux/linux.orig/net/Makefile src/linux/linux/net/Makefile +--- src/linux/linux.orig/net/Makefile 2003-07-04 04:12:29.000000000 -0400 ++++ src/linux/linux/net/Makefile 2004-05-31 02:18:03.000000000 -0400 +@@ -51,6 +51,7 @@ + ifeq ($(CONFIG_NET),y) + obj-$(CONFIG_MODULES) += netsyms.o + obj-$(CONFIG_SYSCTL) += sysctl_net.o ++obj-$(CONFIG_NETSWAP) += netswapping.o + endif + + include $(TOPDIR)/Rules.make +diff -Nurb src/linux/linux.orig/net/core/sock.c src/linux/linux/net/core/sock.c +--- src/linux/linux.orig/net/core/sock.c 2003-10-14 04:09:32.000000000 -0400 ++++ src/linux/linux/net/core/sock.c 2004-05-31 02:18:03.000000000 -0400 +@@ -402,6 +402,21 @@ + ret = -ENONET; + break; + #endif ++#ifdef CONFIG_NETSWAP ++ case SO_SWAPPING: ++ if (valbool) { ++ if (!sk->swapping) { ++ netswap_sock_count ++; ++ } ++ sk->swapping ++; ++ } else if (sk->swapping > 0) { ++ sk->swapping --; ++ if (!sk->swapping) { ++ netswap_sock_count --; ++ } ++ } ++ break; ++#endif + /* We implement the SO_SNDLOWAT etc to + not be settable (1003.1g 5.3) */ + default: +@@ -552,6 +567,12 @@ + goto lenout; + } + ++#ifdef CONFIG_NETSWAP ++ case SO_SWAPPING: ++ v.val = sk->swapping; ++ break; ++#endif ++ + /* Dubious BSD thing... Probably nobody even uses it, but + * the UNIX standard wants it for whatever reason... -DaveM + */ +diff -Nurb src/linux/linux.orig/net/ipv4/tcp_ipv4.c src/linux/linux/net/ipv4/tcp_ipv4.c +--- src/linux/linux.orig/net/ipv4/tcp_ipv4.c 2003-10-14 04:09:33.000000000 -0400 ++++ src/linux/linux/net/ipv4/tcp_ipv4.c 2004-05-31 02:18:03.000000000 -0400 +@@ -1657,6 +1657,12 @@ + if (filter && sk_filter(skb, filter)) + goto discard; + #endif /* CONFIG_FILTER */ ++#ifdef CONFIG_NETSWAP ++ /* tcp doesn't use sock_queue_rcv_skb() ... */ ++ /* an inline function defined in net/netswapping.h */ ++ if (netswap_low_memory(sk, skb)) ++ goto discard; ++#endif /* CONFIG_NETSWAP */ + + IP_INC_STATS_BH(IpInDelivers); + +diff -Nurb src/linux/linux.orig/net/ipv6/tcp_ipv6.c src/linux/linux/net/ipv6/tcp_ipv6.c +--- src/linux/linux.orig/net/ipv6/tcp_ipv6.c 2003-10-14 04:09:34.000000000 -0400 ++++ src/linux/linux/net/ipv6/tcp_ipv6.c 2004-05-31 02:18:03.000000000 -0400 +@@ -1424,6 +1424,12 @@ + if (filter && sk_filter(skb, filter)) + goto discard; + #endif /* CONFIG_FILTER */ ++#ifdef CONFIG_NETSWAP ++ /* tcp doesn't use sock_queue_rcv_skb() ... */ ++ /* an inline function defined in net/netswapping.h */ ++ if (netswap_low_memory(sk, skb)) ++ goto discard; ++#endif /* CONFIG_NETSWAP */ + + /* + * socket locking is here for SMP purposes as backlog rcv +diff -Nurb src/linux/linux.orig/net/netswapping.c src/linux/linux/net/netswapping.c +--- src/linux/linux.orig/net/netswapping.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/netswapping.c 2004-05-31 02:18:03.000000000 -0400 +@@ -0,0 +1,76 @@ ++/* ++ * linux/net/swapping.c ++ * ++ * Support paging over network connections (inet only) ++ * ++ * (c) 2000 Claus-Justus Heine ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++unsigned int netswap_dropped; /* statistics */ ++unsigned int netswap_free_pages_min; ++int netswap_sock_count; /* how many sockets have swapping option set */ ++ ++#ifdef CONFIG_SYSCTL ++ ++static ctl_table netswap_table[] = { ++ {NET_SWAP_DROPPED, "dropped", ++ &netswap_dropped, sizeof(int), 0644, NULL, &proc_dointvec }, ++ {NET_SWAP_DROP_THRESHOLD, "threshold", ++ &netswap_free_pages_min, sizeof(int), 0644, NULL, &proc_dointvec }, ++ {NET_SWAP_SOCK_COUNT, "sock_count", ++ &netswap_sock_count, sizeof(int), 0444, NULL, &proc_dointvec }, ++ {0}, ++}; ++ ++static struct ctl_table_header *netswap_sysctl_header; ++ ++static ctl_table netswap_net_table[] = { ++ {CTL_NETSWAP, "swapping", NULL, 0, 0555, netswap_table}, ++ {0} ++}; ++ ++static ctl_table netswap_root_table[] = { ++ {CTL_NET, "net", NULL, 0, 0555, netswap_net_table}, ++ {0} ++}; ++ ++#endif ++ ++int __init netswap_init(void) ++{ ++ /* drop packets when below this threshold */ ++ netswap_free_pages_min = 32 /* freepages.min */; ++#ifdef CONFIG_SYSCTL ++ netswap_sysctl_header = register_sysctl_table(netswap_root_table, 0); ++#endif ++ return 0; ++} ++ ++void __exit netswap_exit(void) ++{ ++#ifdef CONFIG_SYSCTL ++ unregister_sysctl_table(netswap_sysctl_header); ++#endif ++} ++ ++/* linux/init.h -- VERY nice :-) ++ * ++ * On the other hand, we have no control over the order the initcalls ++ * are performed ... ++ * ++ * Actually, we are not compiled as module ... ++ */ ++ ++module_init(netswap_init) ++module_exit(netswap_exit) +diff -Nurb src/linux/linux.orig/net/netsyms.c src/linux/linux/net/netsyms.c +--- src/linux/linux.orig/net/netsyms.c 2004-05-31 02:02:49.000000000 -0400 ++++ src/linux/linux/net/netsyms.c 2004-05-31 02:18:03.000000000 -0400 +@@ -601,4 +601,10 @@ + EXPORT_SYMBOL(wireless_send_event); + #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ + ++#ifdef CONFIG_NETSWAP ++EXPORT_SYMBOL(netswap_sock_count); ++EXPORT_SYMBOL(netswap_free_pages_min); ++EXPORT_SYMBOL(netswap_dropped); ++#endif ++ + #endif /* CONFIG_NET */ +diff -Nurb src/linux/linux.orig/net/packet/af_packet.c src/linux/linux/net/packet/af_packet.c +--- src/linux/linux.orig/net/packet/af_packet.c 2003-10-14 04:09:35.000000000 -0400 ++++ src/linux/linux/net/packet/af_packet.c 2004-05-31 02:18:03.000000000 -0400 +@@ -449,6 +449,12 @@ + snaplen = res; + } + #endif /* CONFIG_FILTER */ ++#ifdef CONFIG_NETSWAP ++ /* packet doesn't use sock_queue_rcv_skb() ... */ ++ /* an inline function defined in net/netswapping.h */ ++ if (netswap_low_memory(sk, skb)) ++ goto drop_n_restore; ++#endif /* CONFIG_NETSWAP */ + + if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) + goto drop_n_acct; +@@ -496,7 +502,7 @@ + po->stats.tp_drops++; + spin_unlock(&sk->receive_queue.lock); + +-#ifdef CONFIG_FILTER ++#if defined(CONFIG_FILTER) || defined(CONFIG_NETSWAP) + drop_n_restore: + #endif + if (skb_head != skb->data && skb_shared(skb)) { +@@ -557,6 +563,12 @@ + snaplen = res; + } + #endif ++#ifdef CONFIG_NETSWAP ++ /* packet doesn't use sock_queue_rcv_skb() ... */ ++ /* an inline function defined in net/netswapping.h */ ++ if (netswap_low_memory(sk, skb)) ++ goto drop_n_restore; ++#endif /* CONFIG_NETSWAP */ + + if (sk->type == SOCK_DGRAM) { + macoff = netoff = TPACKET_ALIGN(TPACKET_HDRLEN) + 16; +diff -Nurb src/linux/linux.orig/net/sunrpc/sched.c src/linux/linux/net/sunrpc/sched.c +--- src/linux/linux.orig/net/sunrpc/sched.c 2003-07-04 04:12:33.000000000 -0400 ++++ src/linux/linux/net/sunrpc/sched.c 2004-05-31 02:18:03.000000000 -0400 +@@ -79,10 +79,11 @@ + */ + static spinlock_t rpc_sched_lock = SPIN_LOCK_UNLOCKED; + ++#if CONFIG_SWAP_VIA_NFS || CONFIG_SWAP_VIA_NFS_MODULE + /* + * This is the last-ditch buffer for NFS swap requests + */ +-static u32 swap_buffer[PAGE_SIZE >> 2]; ++static u32 swap_buffer[2*PAGE_SIZE >> 2]; + static long swap_buffer_used; + + /* +@@ -96,6 +97,7 @@ + { + clear_bit(1, &swap_buffer_used); + } ++#endif + + /* + * Disable the timer for a given RPC task. Should be called with +@@ -501,6 +503,7 @@ + __rpc_execute(struct rpc_task *task) + { + int status = 0; ++ unsigned long alloc_flag = current->flags & PF_MEMALLOC; + + dprintk("RPC: %4d rpc_execute flgs %x\n", + task->tk_pid, task->tk_flags); +@@ -510,6 +513,13 @@ + return 0; + } + ++ if (task->tk_flags & RPC_TASK_SWAPPER) { ++ if (!current->flags & PF_MEMALLOC) { ++ dprintk("__rpc_execute: Setting PF_MEMALLOC\n"); ++ } ++ current->flags |= PF_MEMALLOC; ++ } ++ + restarted: + while (1) { + /* +@@ -554,7 +564,8 @@ + rpc_set_sleeping(task); + if (RPC_IS_ASYNC(task)) { + spin_unlock_bh(&rpc_queue_lock); +- return 0; ++ status = 0; ++ goto out; + } + } + spin_unlock_bh(&rpc_queue_lock); +@@ -563,7 +574,12 @@ + /* sync task: sleep here */ + dprintk("RPC: %4d sync task going to sleep\n", + task->tk_pid); +- if (current->pid == rpciod_pid) ++ /* it's ok to wait for rpciod when swapping, ++ * because this means it needed memory and is ++ * doing the swap-out itself. ++ */ ++ if (current->pid == rpciod_pid && ++ !(task->tk_flags & RPC_TASK_SWAPPER)) + printk(KERN_ERR "RPC: rpciod waiting on sync task!\n"); + + __wait_event(task->tk_wait, !RPC_IS_SLEEPING(task)); +@@ -608,6 +624,10 @@ + /* Release all resources associated with the task */ + rpc_release_task(task); + ++ out: ++ if (!alloc_flag) { ++ current->flags &= ~PF_MEMALLOC; ++ } + return status; + } + +@@ -699,10 +719,16 @@ + { + u32 *buffer; + int gfp; ++ unsigned long alloc_flag = current->flags & PF_MEMALLOC; ++ void *ret = NULL; + +- if (flags & RPC_TASK_SWAPPER) ++ if (flags & RPC_TASK_SWAPPER) { + gfp = GFP_ATOMIC; +- else if (flags & RPC_TASK_ASYNC) ++ if (!(current->flags & PF_MEMALLOC)) { ++ dprintk("rpc_allocate: Setting PF_MEMALLOC\n"); ++ } ++ current->flags |= PF_MEMALLOC; ++ } else if (flags & RPC_TASK_ASYNC) + gfp = GFP_RPC; + else + gfp = GFP_KERNEL; +@@ -710,29 +736,44 @@ + do { + if ((buffer = (u32 *) kmalloc(size, gfp)) != NULL) { + dprintk("RPC: allocated buffer %p\n", buffer); +- return buffer; ++ ret = buffer; ++ goto out; + } ++#if CONFIG_SWAP_VIA_NFS || CONFIG_SWAP_VIA_NFS_MODULE + if ((flags & RPC_TASK_SWAPPER) && size <= sizeof(swap_buffer) + && rpc_lock_swapbuf()) { + dprintk("RPC: used last-ditch swap buffer\n"); +- return swap_buffer; ++ ret = swap_buffer; ++ goto out; ++#endif ++ } ++ if (flags & RPC_TASK_ASYNC) { ++ ret = NULL; ++ goto out; + } +- if (flags & RPC_TASK_ASYNC) +- return NULL; + yield(); + } while (!signalled()); + +- return NULL; ++ out: ++ if (!alloc_flag) { ++ current->flags &= ~PF_MEMALLOC; ++ } ++ return ret; + } + + void + rpc_free(void *buffer) + { ++#if CONFIG_SWAP_VIA_NFS || CONFIG_SWAP_VIA_NFS_MODULE + if (buffer != swap_buffer) { ++#endif + kfree(buffer); + return; ++#if CONFIG_SWAP_VIA_NFS || CONFIG_SWAP_VIA_NFS_MODULE + } + rpc_unlock_swapbuf(); ++ printk("RPC: Released swap buffer\n"); ++#endif + } + + /* +diff -Nurb src/linux/linux.orig/net/sunrpc/xprt.c src/linux/linux/net/sunrpc/xprt.c +--- src/linux/linux.orig/net/sunrpc/xprt.c 2003-07-04 04:12:33.000000000 -0400 ++++ src/linux/linux/net/sunrpc/xprt.c 2004-05-31 02:18:03.000000000 -0400 +@@ -139,7 +139,7 @@ + __xprt_lock_write(struct rpc_xprt *xprt, struct rpc_task *task) + { + if (!xprt->snd_task) { +- if (xprt->nocong || __xprt_get_cong(xprt, task)) ++ if (__xprt_get_cong(xprt, task)) + xprt->snd_task = task; + } + if (xprt->snd_task != task) { +@@ -179,7 +179,7 @@ + if (!task) + return; + } +- if (xprt->nocong || __xprt_get_cong(xprt, task)) ++ if (__xprt_get_cong(xprt, task)) + xprt->snd_task = task; + } + +@@ -276,6 +276,9 @@ + { + struct rpc_rqst *req = task->tk_rqstp; + ++ if (xprt->nocong || RPC_IS_SWAPPER(task)) ++ return 1; ++ + if (req->rq_cong) + return 1; + dprintk("RPC: %4d xprt_cwnd_limited cong = %ld cwnd = %ld\n", diff --git a/obsolete-buildroot/sources/openwrt/kernel/patches/140-ebtables-brnf-5.patch b/obsolete-buildroot/sources/openwrt/kernel/patches/140-ebtables-brnf-5.patch new file mode 100644 index 0000000000..707919e2bd --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/kernel/patches/140-ebtables-brnf-5.patch @@ -0,0 +1,6336 @@ +diff -Nurb src/linux/linux.stock/include/linux/if_bridge.h src/linux/linux/include/linux/if_bridge.h +--- src/linux/linux.stock/include/linux/if_bridge.h 2003-10-14 04:09:25.000000000 -0400 ++++ src/linux/linux/include/linux/if_bridge.h 2004-07-10 23:46:39.000000000 -0400 +@@ -102,7 +102,8 @@ + struct net_bridge_port; + + extern int (*br_ioctl_hook)(unsigned long arg); +-extern void (*br_handle_frame_hook)(struct sk_buff *skb); ++extern int (*br_handle_frame_hook)(struct sk_buff *skb); ++extern int (*br_should_route_hook)(struct sk_buff **pskb); + + #endif + +diff -Nurb src/linux/linux.stock/include/linux/netfilter.h src/linux/linux/include/linux/netfilter.h +--- src/linux/linux.stock/include/linux/netfilter.h 2004-07-10 23:30:09.000000000 -0400 ++++ src/linux/linux/include/linux/netfilter.h 2004-07-10 23:46:39.000000000 -0400 +@@ -119,17 +119,23 @@ + /* This is gross, but inline doesn't cut it for avoiding the function + call in fast path: gcc doesn't inline (needs value tracking?). --RR */ + #ifdef CONFIG_NETFILTER_DEBUG +-#define NF_HOOK nf_hook_slow ++#define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \ ++nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn), INT_MIN) ++#define NF_HOOK_THRESH nf_hook_slow + #else + #define NF_HOOK(pf, hook, skb, indev, outdev, okfn) \ + (list_empty(&nf_hooks[(pf)][(hook)]) \ + ? (okfn)(skb) \ +- : nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn))) ++ : nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn), INT_MIN)) ++#define NF_HOOK_THRESH(pf, hook, skb, indev, outdev, okfn, thresh) \ ++(list_empty(&nf_hooks[(pf)][(hook)]) \ ++ ? (okfn)(skb) \ ++ : nf_hook_slow((pf), (hook), (skb), (indev), (outdev), (okfn), (thresh))) + #endif + + int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, + struct net_device *indev, struct net_device *outdev, +- int (*okfn)(struct sk_buff *)); ++ int (*okfn)(struct sk_buff *), int thresh); + + /* Call setsockopt() */ + int nf_setsockopt(struct sock *sk, int pf, int optval, char *opt, +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_802_3.h src/linux/linux/include/linux/netfilter_bridge/ebt_802_3.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_802_3.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_802_3.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,60 @@ ++#ifndef __LINUX_BRIDGE_EBT_802_3_H ++#define __LINUX_BRIDGE_EBT_802_3_H ++ ++#define EBT_802_3_SAP 0x01 ++#define EBT_802_3_TYPE 0x02 ++ ++#define EBT_802_3_MATCH "802_3" ++ ++/* ++ * If frame has DSAP/SSAP value 0xaa you must check the SNAP type ++ * to discover what kind of packet we're carrying. ++ */ ++#define CHECK_TYPE 0xaa ++ ++/* ++ * Control field may be one or two bytes. If the first byte has ++ * the value 0x03 then the entire length is one byte, otherwise it is two. ++ * One byte controls are used in Unnumbered Information frames. ++ * Two byte controls are used in Numbered Information frames. ++ */ ++#define IS_UI 0x03 ++ ++#define EBT_802_3_MASK (EBT_802_3_SAP | EBT_802_3_TYPE | EBT_802_3) ++ ++/* ui has one byte ctrl, ni has two */ ++struct hdr_ui { ++ uint8_t dsap; ++ uint8_t ssap; ++ uint8_t ctrl; ++ uint8_t orig[3]; ++ uint16_t type; ++}; ++ ++struct hdr_ni { ++ uint8_t dsap; ++ uint8_t ssap; ++ uint16_t ctrl; ++ uint8_t orig[3]; ++ uint16_t type; ++}; ++ ++struct ebt_802_3_hdr { ++ uint8_t daddr[6]; ++ uint8_t saddr[6]; ++ uint16_t len; ++ union { ++ struct hdr_ui ui; ++ struct hdr_ni ni; ++ } llc; ++}; ++ ++struct ebt_802_3_info ++{ ++ uint8_t sap; ++ uint16_t type; ++ uint8_t bitmask; ++ uint8_t invflags; ++}; ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_among.h src/linux/linux/include/linux/netfilter_bridge/ebt_among.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_among.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_among.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,65 @@ ++#ifndef __LINUX_BRIDGE_EBT_AMONG_H ++#define __LINUX_BRIDGE_EBT_AMONG_H ++ ++#define EBT_AMONG_DST 0x01 ++#define EBT_AMONG_SRC 0x02 ++ ++/* Grzegorz Borowiak 2003 ++ * ++ * Write-once-read-many hash table, used for checking if a given ++ * MAC address belongs to a set or not and possibly for checking ++ * if it is related with a given IPv4 address. ++ * ++ * The hash value of an address is its last byte. ++ * ++ * In real-world ethernet addresses, values of the last byte are ++ * evenly distributed and there is no need to consider other bytes. ++ * It would only slow the routines down. ++ * ++ * For MAC address comparison speedup reasons, we introduce a trick. ++ * MAC address is mapped onto an array of two 32-bit integers. ++ * This pair of integers is compared with MAC addresses in the ++ * hash table, which are stored also in form of pairs of integers ++ * (in `cmp' array). This is quick as it requires only two elementary ++ * number comparisons in worst case. Further, we take advantage of ++ * fact that entropy of 3 last bytes of address is larger than entropy ++ * of 3 first bytes. So first we compare 4 last bytes of addresses and ++ * if they are the same we compare 2 first. ++ * ++ * Yes, it is a memory overhead, but in 2003 AD, who cares? ++ */ ++ ++struct ebt_mac_wormhash_tuple ++{ ++ uint32_t cmp[2]; ++ uint32_t ip; ++}; ++ ++struct ebt_mac_wormhash ++{ ++ int table[257]; ++ int poolsize; ++ struct ebt_mac_wormhash_tuple pool[0]; ++}; ++ ++#define ebt_mac_wormhash_size(x) ((x) ? sizeof(struct ebt_mac_wormhash) \ ++ + (x)->poolsize * sizeof(struct ebt_mac_wormhash_tuple) : 0) ++ ++struct ebt_among_info ++{ ++ int wh_dst_ofs; ++ int wh_src_ofs; ++ int bitmask; ++}; ++ ++#define EBT_AMONG_DST_NEG 0x1 ++#define EBT_AMONG_SRC_NEG 0x2 ++ ++#define ebt_among_wh_dst(x) ((x)->wh_dst_ofs ? \ ++ (struct ebt_mac_wormhash*)((char*)(x) + (x)->wh_dst_ofs) : NULL) ++#define ebt_among_wh_src(x) ((x)->wh_src_ofs ? \ ++ (struct ebt_mac_wormhash*)((char*)(x) + (x)->wh_src_ofs) : NULL) ++ ++#define EBT_AMONG_MATCH "among" ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_arp.h src/linux/linux/include/linux/netfilter_bridge/ebt_arp.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_arp.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_arp.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,32 @@ ++#ifndef __LINUX_BRIDGE_EBT_ARP_H ++#define __LINUX_BRIDGE_EBT_ARP_H ++ ++#define EBT_ARP_OPCODE 0x01 ++#define EBT_ARP_HTYPE 0x02 ++#define EBT_ARP_PTYPE 0x04 ++#define EBT_ARP_SRC_IP 0x08 ++#define EBT_ARP_DST_IP 0x10 ++#define EBT_ARP_SRC_MAC 0x20 ++#define EBT_ARP_DST_MAC 0x40 ++#define EBT_ARP_MASK (EBT_ARP_OPCODE | EBT_ARP_HTYPE | EBT_ARP_PTYPE | \ ++ EBT_ARP_SRC_IP | EBT_ARP_DST_IP | EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC) ++#define EBT_ARP_MATCH "arp" ++ ++struct ebt_arp_info ++{ ++ uint16_t htype; ++ uint16_t ptype; ++ uint16_t opcode; ++ uint32_t saddr; ++ uint32_t smsk; ++ uint32_t daddr; ++ uint32_t dmsk; ++ unsigned char smaddr[ETH_ALEN]; ++ unsigned char smmsk[ETH_ALEN]; ++ unsigned char dmaddr[ETH_ALEN]; ++ unsigned char dmmsk[ETH_ALEN]; ++ uint8_t bitmask; ++ uint8_t invflags; ++}; ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_arpreply.h src/linux/linux/include/linux/netfilter_bridge/ebt_arpreply.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_arpreply.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_arpreply.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,11 @@ ++#ifndef __LINUX_BRIDGE_EBT_ARPREPLY_H ++#define __LINUX_BRIDGE_EBT_ARPREPLY_H ++ ++struct ebt_arpreply_info ++{ ++ unsigned char mac[ETH_ALEN]; ++ int target; ++}; ++#define EBT_ARPREPLY_TARGET "arpreply" ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_ip.h src/linux/linux/include/linux/netfilter_bridge/ebt_ip.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_ip.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_ip.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,43 @@ ++/* ++ * ebt_ip ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * April, 2002 ++ * ++ * Changes: ++ * added ip-sport and ip-dport ++ * Innominate Security Technologies AG ++ * September, 2002 ++ */ ++ ++#ifndef __LINUX_BRIDGE_EBT_IP_H ++#define __LINUX_BRIDGE_EBT_IP_H ++ ++#define EBT_IP_SOURCE 0x01 ++#define EBT_IP_DEST 0x02 ++#define EBT_IP_TOS 0x04 ++#define EBT_IP_PROTO 0x08 ++#define EBT_IP_SPORT 0x10 ++#define EBT_IP_DPORT 0x20 ++#define EBT_IP_MASK (EBT_IP_SOURCE | EBT_IP_DEST | EBT_IP_TOS | EBT_IP_PROTO |\ ++ EBT_IP_SPORT | EBT_IP_DPORT ) ++#define EBT_IP_MATCH "ip" ++ ++// the same values are used for the invflags ++struct ebt_ip_info ++{ ++ uint32_t saddr; ++ uint32_t daddr; ++ uint32_t smsk; ++ uint32_t dmsk; ++ uint8_t tos; ++ uint8_t protocol; ++ uint8_t bitmask; ++ uint8_t invflags; ++ uint16_t sport[2]; ++ uint16_t dport[2]; ++}; ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_limit.h src/linux/linux/include/linux/netfilter_bridge/ebt_limit.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_limit.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_limit.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,23 @@ ++#ifndef __LINUX_BRIDGE_EBT_LIMIT_H ++#define __LINUX_BRIDGE_EBT_LIMIT_H ++ ++#define EBT_LIMIT_MATCH "limit" ++ ++/* timings are in milliseconds. */ ++#define EBT_LIMIT_SCALE 10000 ++ ++/* 1/10,000 sec period => max of 10,000/sec. Min rate is then 429490 ++ seconds, or one every 59 hours. */ ++ ++struct ebt_limit_info ++{ ++ u_int32_t avg; /* Average secs between packets * scale */ ++ u_int32_t burst; /* Period multiplier for upper limit. */ ++ ++ /* Used internally by the kernel */ ++ unsigned long prev; ++ u_int32_t credit; ++ u_int32_t credit_cap, cost; ++}; ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_log.h src/linux/linux/include/linux/netfilter_bridge/ebt_log.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_log.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_log.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,17 @@ ++#ifndef __LINUX_BRIDGE_EBT_LOG_H ++#define __LINUX_BRIDGE_EBT_LOG_H ++ ++#define EBT_LOG_IP 0x01 // if the frame is made by ip, log the ip information ++#define EBT_LOG_ARP 0x02 ++#define EBT_LOG_MASK (EBT_LOG_IP | EBT_LOG_ARP) ++#define EBT_LOG_PREFIX_SIZE 30 ++#define EBT_LOG_WATCHER "log" ++ ++struct ebt_log_info ++{ ++ uint8_t loglevel; ++ uint8_t prefix[EBT_LOG_PREFIX_SIZE]; ++ uint32_t bitmask; ++}; ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_mark_m.h src/linux/linux/include/linux/netfilter_bridge/ebt_mark_m.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_mark_m.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_mark_m.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,15 @@ ++#ifndef __LINUX_BRIDGE_EBT_MARK_M_H ++#define __LINUX_BRIDGE_EBT_MARK_M_H ++ ++#define EBT_MARK_AND 0x01 ++#define EBT_MARK_OR 0x02 ++#define EBT_MARK_MASK (EBT_MARK_AND | EBT_MARK_OR) ++struct ebt_mark_m_info ++{ ++ unsigned long mark, mask; ++ uint8_t invert; ++ uint8_t bitmask; ++}; ++#define EBT_MARK_MATCH "mark_m" ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_mark_t.h src/linux/linux/include/linux/netfilter_bridge/ebt_mark_t.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_mark_t.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_mark_t.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,12 @@ ++#ifndef __LINUX_BRIDGE_EBT_MARK_T_H ++#define __LINUX_BRIDGE_EBT_MARK_T_H ++ ++struct ebt_mark_t_info ++{ ++ unsigned long mark; ++ // EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN ++ int target; ++}; ++#define EBT_MARK_TARGET "mark" ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_nat.h src/linux/linux/include/linux/netfilter_bridge/ebt_nat.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_nat.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_nat.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,13 @@ ++#ifndef __LINUX_BRIDGE_EBT_NAT_H ++#define __LINUX_BRIDGE_EBT_NAT_H ++ ++struct ebt_nat_info ++{ ++ unsigned char mac[ETH_ALEN]; ++ // EBT_ACCEPT, EBT_DROP, EBT_CONTINUE or EBT_RETURN ++ int target; ++}; ++#define EBT_SNAT_TARGET "snat" ++#define EBT_DNAT_TARGET "dnat" ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_pkttype.h src/linux/linux/include/linux/netfilter_bridge/ebt_pkttype.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_pkttype.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_pkttype.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,11 @@ ++#ifndef __LINUX_BRIDGE_EBT_PKTTYPE_H ++#define __LINUX_BRIDGE_EBT_PKTTYPE_H ++ ++struct ebt_pkttype_info ++{ ++ uint8_t pkt_type; ++ uint8_t invert; ++}; ++#define EBT_PKTTYPE_MATCH "pkttype" ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_redirect.h src/linux/linux/include/linux/netfilter_bridge/ebt_redirect.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_redirect.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_redirect.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,11 @@ ++#ifndef __LINUX_BRIDGE_EBT_REDIRECT_H ++#define __LINUX_BRIDGE_EBT_REDIRECT_H ++ ++struct ebt_redirect_info ++{ ++ // EBT_ACCEPT, EBT_DROP or EBT_CONTINUE or EBT_RETURN ++ int target; ++}; ++#define EBT_REDIRECT_TARGET "redirect" ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_stp.h src/linux/linux/include/linux/netfilter_bridge/ebt_stp.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_stp.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_stp.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,46 @@ ++#ifndef __LINUX_BRIDGE_EBT_STP_H ++#define __LINUX_BRIDGE_EBT_STP_H ++ ++#define EBT_STP_TYPE 0x0001 ++ ++#define EBT_STP_FLAGS 0x0002 ++#define EBT_STP_ROOTPRIO 0x0004 ++#define EBT_STP_ROOTADDR 0x0008 ++#define EBT_STP_ROOTCOST 0x0010 ++#define EBT_STP_SENDERPRIO 0x0020 ++#define EBT_STP_SENDERADDR 0x0040 ++#define EBT_STP_PORT 0x0080 ++#define EBT_STP_MSGAGE 0x0100 ++#define EBT_STP_MAXAGE 0x0200 ++#define EBT_STP_HELLOTIME 0x0400 ++#define EBT_STP_FWDD 0x0800 ++ ++#define EBT_STP_MASK 0x0fff ++#define EBT_STP_CONFIG_MASK 0x0ffe ++ ++#define EBT_STP_MATCH "stp" ++ ++struct ebt_stp_config_info ++{ ++ uint8_t flags; ++ uint16_t root_priol, root_priou; ++ char root_addr[6], root_addrmsk[6]; ++ uint32_t root_costl, root_costu; ++ uint16_t sender_priol, sender_priou; ++ char sender_addr[6], sender_addrmsk[6]; ++ uint16_t portl, portu; ++ uint16_t msg_agel, msg_ageu; ++ uint16_t max_agel, max_ageu; ++ uint16_t hello_timel, hello_timeu; ++ uint16_t forward_delayl, forward_delayu; ++}; ++ ++struct ebt_stp_info ++{ ++ uint8_t type; ++ struct ebt_stp_config_info config; ++ uint16_t bitmask; ++ uint16_t invflags; ++}; ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebt_vlan.h src/linux/linux/include/linux/netfilter_bridge/ebt_vlan.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebt_vlan.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebt_vlan.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,20 @@ ++#ifndef __LINUX_BRIDGE_EBT_VLAN_H ++#define __LINUX_BRIDGE_EBT_VLAN_H ++ ++#define EBT_VLAN_ID 0x01 ++#define EBT_VLAN_PRIO 0x02 ++#define EBT_VLAN_ENCAP 0x04 ++#define EBT_VLAN_MASK (EBT_VLAN_ID | EBT_VLAN_PRIO | EBT_VLAN_ENCAP) ++#define EBT_VLAN_MATCH "vlan" ++ ++struct ebt_vlan_info { ++ uint16_t id; /* VLAN ID {1-4095} */ ++ uint8_t prio; /* VLAN User Priority {0-7} */ ++ uint16_t encap; /* VLAN Encapsulated frame code {0-65535} */ ++ uint8_t bitmask; /* Args bitmask bit 1=1 - ID arg, ++ bit 2=1 User-Priority arg, bit 3=1 encap*/ ++ uint8_t invflags; /* Inverse bitmask bit 1=1 - inversed ID arg, ++ bit 2=1 - inversed Pirority arg */ ++}; ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge/ebtables.h src/linux/linux/include/linux/netfilter_bridge/ebtables.h +--- src/linux/linux.stock/include/linux/netfilter_bridge/ebtables.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_bridge/ebtables.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,361 @@ ++/* ++ * ebtables ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * ebtables.c,v 2.0, September, 2002 ++ * ++ * This code is stongly inspired on the iptables code which is ++ * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling ++ */ ++ ++#ifndef __LINUX_BRIDGE_EFF_H ++#define __LINUX_BRIDGE_EFF_H ++#include ++#include ++#include ++ ++#define EBT_TABLE_MAXNAMELEN 32 ++#define EBT_CHAIN_MAXNAMELEN EBT_TABLE_MAXNAMELEN ++#define EBT_FUNCTION_MAXNAMELEN EBT_TABLE_MAXNAMELEN ++ ++// verdicts >0 are "branches" ++#define EBT_ACCEPT -1 ++#define EBT_DROP -2 ++#define EBT_CONTINUE -3 ++#define EBT_RETURN -4 ++#define NUM_STANDARD_TARGETS 4 ++ ++struct ebt_counter ++{ ++ uint64_t pcnt; ++ uint64_t bcnt; ++}; ++ ++struct ebt_entries { ++ // this field is always set to zero ++ // See EBT_ENTRY_OR_ENTRIES. ++ // Must be same size as ebt_entry.bitmask ++ unsigned int distinguisher; ++ // the chain name ++ char name[EBT_CHAIN_MAXNAMELEN]; ++ // counter offset for this chain ++ unsigned int counter_offset; ++ // one standard (accept, drop, return) per hook ++ int policy; ++ // nr. of entries ++ unsigned int nentries; ++ // entry list ++ char data[0]; ++}; ++ ++// used for the bitmask of struct ebt_entry ++ ++// This is a hack to make a difference between an ebt_entry struct and an ++// ebt_entries struct when traversing the entries from start to end. ++// Using this simplifies the code alot, while still being able to use ++// ebt_entries. ++// Contrary, iptables doesn't use something like ebt_entries and therefore uses ++// different techniques for naming the policy and such. So, iptables doesn't ++// need a hack like this. ++#define EBT_ENTRY_OR_ENTRIES 0x01 ++// these are the normal masks ++#define EBT_NOPROTO 0x02 ++#define EBT_802_3 0x04 ++#define EBT_SOURCEMAC 0x08 ++#define EBT_DESTMAC 0x10 ++#define EBT_F_MASK (EBT_NOPROTO | EBT_802_3 | EBT_SOURCEMAC | EBT_DESTMAC \ ++ | EBT_ENTRY_OR_ENTRIES) ++ ++#define EBT_IPROTO 0x01 ++#define EBT_IIN 0x02 ++#define EBT_IOUT 0x04 ++#define EBT_ISOURCE 0x8 ++#define EBT_IDEST 0x10 ++#define EBT_ILOGICALIN 0x20 ++#define EBT_ILOGICALOUT 0x40 ++#define EBT_INV_MASK (EBT_IPROTO | EBT_IIN | EBT_IOUT | EBT_ILOGICALIN \ ++ | EBT_ILOGICALOUT | EBT_ISOURCE | EBT_IDEST) ++ ++struct ebt_entry_match ++{ ++ union { ++ char name[EBT_FUNCTION_MAXNAMELEN]; ++ struct ebt_match *match; ++ } u; ++ // size of data ++ unsigned int match_size; ++ unsigned char data[0]; ++}; ++ ++struct ebt_entry_watcher ++{ ++ union { ++ char name[EBT_FUNCTION_MAXNAMELEN]; ++ struct ebt_watcher *watcher; ++ } u; ++ // size of data ++ unsigned int watcher_size; ++ unsigned char data[0]; ++}; ++ ++struct ebt_entry_target ++{ ++ union { ++ char name[EBT_FUNCTION_MAXNAMELEN]; ++ struct ebt_target *target; ++ } u; ++ // size of data ++ unsigned int target_size; ++ unsigned char data[0]; ++}; ++ ++#define EBT_STANDARD_TARGET "standard" ++struct ebt_standard_target ++{ ++ struct ebt_entry_target target; ++ int verdict; ++}; ++ ++// one entry ++struct ebt_entry { ++ // this needs to be the first field ++ unsigned int bitmask; ++ unsigned int invflags; ++ uint16_t ethproto; ++ // the physical in-dev ++ char in[IFNAMSIZ]; ++ // the logical in-dev ++ char logical_in[IFNAMSIZ]; ++ // the physical out-dev ++ char out[IFNAMSIZ]; ++ // the logical out-dev ++ char logical_out[IFNAMSIZ]; ++ unsigned char sourcemac[ETH_ALEN]; ++ unsigned char sourcemsk[ETH_ALEN]; ++ unsigned char destmac[ETH_ALEN]; ++ unsigned char destmsk[ETH_ALEN]; ++ // sizeof ebt_entry + matches ++ unsigned int watchers_offset; ++ // sizeof ebt_entry + matches + watchers ++ unsigned int target_offset; ++ // sizeof ebt_entry + matches + watchers + target ++ unsigned int next_offset; ++ unsigned char elems[0]; ++}; ++ ++struct ebt_replace ++{ ++ char name[EBT_TABLE_MAXNAMELEN]; ++ unsigned int valid_hooks; ++ // nr of rules in the table ++ unsigned int nentries; ++ // total size of the entries ++ unsigned int entries_size; ++ // start of the chains ++ struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; ++ // nr of counters userspace expects back ++ unsigned int num_counters; ++ // where the kernel will put the old counters ++ struct ebt_counter *counters; ++ char *entries; ++}; ++ ++// [gs]etsockopt numbers ++#define EBT_BASE_CTL 128 ++ ++#define EBT_SO_SET_ENTRIES (EBT_BASE_CTL) ++#define EBT_SO_SET_COUNTERS (EBT_SO_SET_ENTRIES+1) ++#define EBT_SO_SET_MAX (EBT_SO_SET_COUNTERS+1) ++ ++#define EBT_SO_GET_INFO (EBT_BASE_CTL) ++#define EBT_SO_GET_ENTRIES (EBT_SO_GET_INFO+1) ++#define EBT_SO_GET_INIT_INFO (EBT_SO_GET_ENTRIES+1) ++#define EBT_SO_GET_INIT_ENTRIES (EBT_SO_GET_INIT_INFO+1) ++#define EBT_SO_GET_MAX (EBT_SO_GET_INIT_ENTRIES+1) ++ ++#ifdef __KERNEL__ ++ ++// return values for match() functions ++#define EBT_MATCH 0 ++#define EBT_NOMATCH 1 ++ ++struct ebt_match ++{ ++ struct list_head list; ++ const char name[EBT_FUNCTION_MAXNAMELEN]; ++ // 0 == it matches ++ int (*match)(const struct sk_buff *skb, const struct net_device *in, ++ const struct net_device *out, const void *matchdata, ++ unsigned int datalen); ++ // 0 == let it in ++ int (*check)(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *matchdata, unsigned int datalen); ++ void (*destroy)(void *matchdata, unsigned int datalen); ++ struct module *me; ++}; ++ ++struct ebt_watcher ++{ ++ struct list_head list; ++ const char name[EBT_FUNCTION_MAXNAMELEN]; ++ void (*watcher)(const struct sk_buff *skb, const struct net_device *in, ++ const struct net_device *out, const void *watcherdata, ++ unsigned int datalen); ++ // 0 == let it in ++ int (*check)(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *watcherdata, unsigned int datalen); ++ void (*destroy)(void *watcherdata, unsigned int datalen); ++ struct module *me; ++}; ++ ++struct ebt_target ++{ ++ struct list_head list; ++ const char name[EBT_FUNCTION_MAXNAMELEN]; ++ // returns one of the standard verdicts ++ int (*target)(struct sk_buff **pskb, unsigned int hooknr, ++ const struct net_device *in, const struct net_device *out, ++ const void *targetdata, unsigned int datalen); ++ // 0 == let it in ++ int (*check)(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *targetdata, unsigned int datalen); ++ void (*destroy)(void *targetdata, unsigned int datalen); ++ struct module *me; ++}; ++ ++// used for jumping from and into user defined chains (udc) ++struct ebt_chainstack ++{ ++ struct ebt_entries *chaininfo; // pointer to chain data ++ struct ebt_entry *e; // pointer to entry data ++ unsigned int n; // n'th entry ++}; ++ ++struct ebt_table_info ++{ ++ // total size of the entries ++ unsigned int entries_size; ++ unsigned int nentries; ++ // pointers to the start of the chains ++ struct ebt_entries *hook_entry[NF_BR_NUMHOOKS]; ++ // room to maintain the stack used for jumping from and into udc ++ struct ebt_chainstack **chainstack; ++ char *entries; ++ struct ebt_counter counters[0] ____cacheline_aligned; ++}; ++ ++struct ebt_table ++{ ++ struct list_head list; ++ char name[EBT_TABLE_MAXNAMELEN]; ++ struct ebt_replace *table; ++ unsigned int valid_hooks; ++ rwlock_t lock; ++ // e.g. could be the table explicitly only allows certain ++ // matches, targets, ... 0 == let it in ++ int (*check)(const struct ebt_table_info *info, ++ unsigned int valid_hooks); ++ // the data used by the kernel ++ struct ebt_table_info *private; ++}; ++ ++#define EBT_ALIGN(s) (((s) + (__alignof__(struct ebt_entry_target)-1)) & \ ++ ~(__alignof__(struct ebt_entry_target)-1)) ++extern int ebt_register_table(struct ebt_table *table); ++extern void ebt_unregister_table(struct ebt_table *table); ++extern int ebt_register_match(struct ebt_match *match); ++extern void ebt_unregister_match(struct ebt_match *match); ++extern int ebt_register_watcher(struct ebt_watcher *watcher); ++extern void ebt_unregister_watcher(struct ebt_watcher *watcher); ++extern int ebt_register_target(struct ebt_target *target); ++extern void ebt_unregister_target(struct ebt_target *target); ++extern unsigned int ebt_do_table(unsigned int hook, struct sk_buff **pskb, ++ const struct net_device *in, const struct net_device *out, ++ struct ebt_table *table); ++ ++ // Used in the kernel match() functions ++#define FWINV(bool,invflg) ((bool) ^ !!(info->invflags & invflg)) ++// True if the hook mask denotes that the rule is in a base chain, ++// used in the check() functions ++#define BASE_CHAIN (hookmask & (1 << NF_BR_NUMHOOKS)) ++// Clear the bit in the hook mask that tells if the rule is on a base chain ++#define CLEAR_BASE_CHAIN_BIT (hookmask &= ~(1 << NF_BR_NUMHOOKS)) ++// True if the target is not a standard target ++#define INVALID_TARGET (info->target < -NUM_STANDARD_TARGETS || info->target >= 0) ++ ++#endif /* __KERNEL__ */ ++ ++// blatently stolen from ip_tables.h ++// fn returns 0 to continue iteration ++#define EBT_MATCH_ITERATE(e, fn, args...) \ ++({ \ ++ unsigned int __i; \ ++ int __ret = 0; \ ++ struct ebt_entry_match *__match; \ ++ \ ++ for (__i = sizeof(struct ebt_entry); \ ++ __i < (e)->watchers_offset; \ ++ __i += __match->match_size + \ ++ sizeof(struct ebt_entry_match)) { \ ++ __match = (void *)(e) + __i; \ ++ \ ++ __ret = fn(__match , ## args); \ ++ if (__ret != 0) \ ++ break; \ ++ } \ ++ if (__ret == 0) { \ ++ if (__i != (e)->watchers_offset) \ ++ __ret = -EINVAL; \ ++ } \ ++ __ret; \ ++}) ++ ++#define EBT_WATCHER_ITERATE(e, fn, args...) \ ++({ \ ++ unsigned int __i; \ ++ int __ret = 0; \ ++ struct ebt_entry_watcher *__watcher; \ ++ \ ++ for (__i = e->watchers_offset; \ ++ __i < (e)->target_offset; \ ++ __i += __watcher->watcher_size + \ ++ sizeof(struct ebt_entry_watcher)) { \ ++ __watcher = (void *)(e) + __i; \ ++ \ ++ __ret = fn(__watcher , ## args); \ ++ if (__ret != 0) \ ++ break; \ ++ } \ ++ if (__ret == 0) { \ ++ if (__i != (e)->target_offset) \ ++ __ret = -EINVAL; \ ++ } \ ++ __ret; \ ++}) ++ ++#define EBT_ENTRY_ITERATE(entries, size, fn, args...) \ ++({ \ ++ unsigned int __i; \ ++ int __ret = 0; \ ++ struct ebt_entry *__entry; \ ++ \ ++ for (__i = 0; __i < (size);) { \ ++ __entry = (void *)(entries) + __i; \ ++ __ret = fn(__entry , ## args); \ ++ if (__ret != 0) \ ++ break; \ ++ if (__entry->bitmask != 0) \ ++ __i += __entry->next_offset; \ ++ else \ ++ __i += sizeof(struct ebt_entries); \ ++ } \ ++ if (__ret == 0) { \ ++ if (__i != (size)) \ ++ __ret = -EINVAL; \ ++ } \ ++ __ret; \ ++}) ++ ++#endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_bridge.h src/linux/linux/include/linux/netfilter_bridge.h +--- src/linux/linux.stock/include/linux/netfilter_bridge.h 2003-07-04 04:12:26.000000000 -0400 ++++ src/linux/linux/include/linux/netfilter_bridge.h 2004-07-10 23:46:39.000000000 -0400 +@@ -6,6 +6,10 @@ + + #include + #include ++#if defined(__KERNEL__) && defined(CONFIG_NETFILTER) ++#include ++#include ++#endif + + /* Bridge Hooks */ + /* After promisc drops, checksum checks. */ +@@ -18,7 +22,76 @@ + #define NF_BR_LOCAL_OUT 3 + /* Packets about to hit the wire. */ + #define NF_BR_POST_ROUTING 4 +-#define NF_BR_NUMHOOKS 5 ++/* Not really a hook, but used for the ebtables broute table */ ++#define NF_BR_BROUTING 5 ++#define NF_BR_NUMHOOKS 6 ++ ++#ifdef __KERNEL__ ++ ++#define BRNF_PKT_TYPE 0x01 ++#define BRNF_BRIDGED_DNAT 0x02 ++#define BRNF_DONT_TAKE_PARENT 0x04 ++#define BRNF_BRIDGED 0x08 ++#define BRNF_NF_BRIDGE_PREROUTING 0x10 ++ ++enum nf_br_hook_priorities { ++ NF_BR_PRI_FIRST = INT_MIN, ++ NF_BR_PRI_NAT_DST_BRIDGED = -300, ++ NF_BR_PRI_FILTER_BRIDGED = -200, ++ NF_BR_PRI_BRNF = 0, ++ NF_BR_PRI_NAT_DST_OTHER = 100, ++ NF_BR_PRI_FILTER_OTHER = 200, ++ NF_BR_PRI_NAT_SRC = 300, ++ NF_BR_PRI_LAST = INT_MAX, ++}; ++ ++#ifdef CONFIG_NETFILTER ++static inline ++struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb) ++{ ++ struct nf_bridge_info **nf_bridge = &(skb->nf_bridge); ++ ++ if ((*nf_bridge = kmalloc(sizeof(**nf_bridge), GFP_ATOMIC)) != NULL) { ++ atomic_set(&(*nf_bridge)->use, 1); ++ (*nf_bridge)->mask = 0; ++ (*nf_bridge)->physindev = (*nf_bridge)->physoutdev = NULL; ++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) ++ (*nf_bridge)->netoutdev = NULL; ++#endif ++ } ++ ++ return *nf_bridge; ++} ++ ++/* Only used in br_forward.c */ ++static inline ++void nf_bridge_maybe_copy_header(struct sk_buff *skb) ++{ ++ if (skb->nf_bridge) { ++ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { ++ memcpy(skb->data - 18, skb->nf_bridge->data, 18); ++ skb_push(skb, 4); ++ } else ++ memcpy(skb->data - 16, skb->nf_bridge->data, 16); ++ } ++} ++ ++static inline ++void nf_bridge_save_header(struct sk_buff *skb) ++{ ++ int header_size = 16; ++ ++ if (skb->protocol == __constant_htons(ETH_P_8021Q)) ++ header_size = 18; ++ memcpy(skb->nf_bridge->data, skb->data - header_size, header_size); ++} + ++struct bridge_skb_cb { ++ union { ++ __u32 ipv4; ++ } daddr; ++}; ++#endif /* CONFIG_NETFILTER */ + ++#endif /* __KERNEL__ */ + #endif +diff -Nurb src/linux/linux.stock/include/linux/netfilter_ipv4/ipt_physdev.h src/linux/linux/include/linux/netfilter_ipv4/ipt_physdev.h +--- src/linux/linux.stock/include/linux/netfilter_ipv4/ipt_physdev.h 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/include/linux/netfilter_ipv4/ipt_physdev.h 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,24 @@ ++#ifndef _IPT_PHYSDEV_H ++#define _IPT_PHYSDEV_H ++ ++#ifdef __KERNEL__ ++#include ++#endif ++ ++#define IPT_PHYSDEV_OP_IN 0x01 ++#define IPT_PHYSDEV_OP_OUT 0x02 ++#define IPT_PHYSDEV_OP_BRIDGED 0x04 ++#define IPT_PHYSDEV_OP_ISIN 0x08 ++#define IPT_PHYSDEV_OP_ISOUT 0x10 ++#define IPT_PHYSDEV_OP_MASK (0x20 - 1) ++ ++struct ipt_physdev_info { ++ char physindev[IFNAMSIZ]; ++ char in_mask[IFNAMSIZ]; ++ char physoutdev[IFNAMSIZ]; ++ char out_mask[IFNAMSIZ]; ++ u_int8_t invert; ++ u_int8_t bitmask; ++}; ++ ++#endif /*_IPT_PHYSDEV_H*/ +diff -Nurb src/linux/linux.stock/include/linux/netfilter_ipv4.h src/linux/linux/include/linux/netfilter_ipv4.h +--- src/linux/linux.stock/include/linux/netfilter_ipv4.h 2004-07-10 23:30:09.000000000 -0400 ++++ src/linux/linux/include/linux/netfilter_ipv4.h 2004-07-10 23:46:39.000000000 -0400 +@@ -54,8 +54,10 @@ + NF_IP_PRI_CONNTRACK_DEFRAG = -400, + NF_IP_PRI_RAW = -300, + NF_IP_PRI_CONNTRACK = -200, ++ NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD = -175, + NF_IP_PRI_MANGLE = -150, + NF_IP_PRI_NAT_DST = -100, ++ NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT = -50, + NF_IP_PRI_FILTER = 0, + NF_IP_PRI_NAT_SRC = 100, + NF_IP_PRI_LAST = INT_MAX, +diff -Nurb src/linux/linux.stock/include/linux/skbuff.h src/linux/linux/include/linux/skbuff.h +--- src/linux/linux.stock/include/linux/skbuff.h 2003-07-04 04:12:26.000000000 -0400 ++++ src/linux/linux/include/linux/skbuff.h 2004-07-10 23:46:39.000000000 -0400 +@@ -92,6 +92,20 @@ + struct nf_ct_info { + struct nf_conntrack *master; + }; ++ ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++struct nf_bridge_info { ++ atomic_t use; ++ struct net_device *physindev; ++ struct net_device *physoutdev; ++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) ++ struct net_device *netoutdev; ++#endif ++ unsigned int mask; ++ unsigned long data[32 / sizeof(unsigned long)]; ++}; ++#endif ++ + #endif + + struct sk_buff_head { +@@ -204,6 +218,9 @@ + #ifdef CONFIG_NETFILTER_DEBUG + unsigned int nf_debug; + #endif ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ struct nf_bridge_info *nf_bridge; /* Saved data about a bridged frame - see br_netfilter.c */ ++#endif + #endif /*CONFIG_NETFILTER*/ + + #if defined(CONFIG_HIPPI) +@@ -1143,6 +1160,20 @@ + if (nfct) + atomic_inc(&nfct->master->use); + } ++ ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++static inline void nf_bridge_put(struct nf_bridge_info *nf_bridge) ++{ ++ if (nf_bridge && atomic_dec_and_test(&nf_bridge->use)) ++ kfree(nf_bridge); ++} ++static inline void nf_bridge_get(struct nf_bridge_info *nf_bridge) ++{ ++ if (nf_bridge) ++ atomic_inc(&nf_bridge->use); ++} ++#endif ++ + #endif + + #endif /* __KERNEL__ */ +diff -Nurb src/linux/linux.stock/include/linux/sysctl.h src/linux/linux/include/linux/sysctl.h +--- src/linux/linux.stock/include/linux/sysctl.h 2004-07-10 23:29:55.000000000 -0400 ++++ src/linux/linux/include/linux/sysctl.h 2004-07-10 23:46:39.000000000 -0400 +@@ -547,6 +547,15 @@ + NET_DECNET_CONF_DEV_STATE = 7 + }; + ++/* /proc/sys/net/bridge */ ++enum { ++ NET_BRIDGE_NF_CALL_ARPTABLES = 1, ++ NET_BRIDGE_NF_CALL_IPTABLES = 2, ++ NET_BRIDGE_NF_CALL_IP6TABLES = 3, ++ NET_BRIDGE_NF_FILTER_VLAN_TAGGED = 4, ++}; ++ ++ + /* CTL_PROC names: */ + + /* CTL_FS names: */ +diff -Nurb src/linux/linux.stock/net/8021q/vlan_dev.c src/linux/linux/net/8021q/vlan_dev.c +--- src/linux/linux.stock/net/8021q/vlan_dev.c 2003-07-04 04:12:29.000000000 -0400 ++++ src/linux/linux/net/8021q/vlan_dev.c 2004-07-10 23:46:39.000000000 -0400 +@@ -503,6 +503,10 @@ + stats->tx_packets++; /* for statics only */ + stats->tx_bytes += skb->len; + ++ skb->protocol = __constant_htons(ETH_P_8021Q); ++ skb->mac.raw -= VLAN_HLEN; ++ skb->nh.raw -= VLAN_HLEN; ++ + dev_queue_xmit(skb); + + return 0; +diff -Nurb src/linux/linux.stock/net/Config.in src/linux/linux/net/Config.in +--- src/linux/linux.stock/net/Config.in 2004-07-10 23:29:49.000000000 -0400 ++++ src/linux/linux/net/Config.in 2004-07-10 23:46:39.000000000 -0400 +@@ -68,6 +68,9 @@ + source net/decnet/Config.in + fi + dep_tristate '802.1d Ethernet Bridging' CONFIG_BRIDGE $CONFIG_INET ++if [ "$CONFIG_BRIDGE" != "n" -a "$CONFIG_NETFILTER" != "n" ]; then ++ source net/bridge/netfilter/Config.in ++fi + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25 + tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB +diff -Nurb src/linux/linux.stock/net/Makefile src/linux/linux/net/Makefile +--- src/linux/linux.stock/net/Makefile 2004-07-10 23:29:49.000000000 -0400 ++++ src/linux/linux/net/Makefile 2004-07-10 23:49:10.000000000 -0400 +@@ -26,6 +26,12 @@ + endif + endif + ++ifneq ($(CONFIG_BRIDGE),n) ++ifneq ($(CONFIG_BRIDGE),) ++subdir-$(CONFIG_BRIDGE) += bridge/netfilter ++endif ++endif ++ + subdir-$(CONFIG_KHTTPD) += khttpd + subdir-$(CONFIG_PACKET) += packet + subdir-$(CONFIG_NET_SCHED) += sched +diff -Nurb src/linux/linux.stock/net/bridge/Makefile src/linux/linux/net/bridge/Makefile +--- src/linux/linux.stock/net/bridge/Makefile 2003-07-04 04:12:30.000000000 -0400 ++++ src/linux/linux/net/bridge/Makefile 2004-07-10 23:46:39.000000000 -0400 +@@ -7,10 +7,17 @@ + # + # Note 2! The CFLAGS definition is now in the main makefile... + ++export-objs := br.o ++ + O_TARGET := bridge.o + obj-y := br.o br_device.o br_fdb.o br_forward.o br_if.o br_input.o \ + br_ioctl.o br_notify.o br_stp.o br_stp_bpdu.o \ + br_stp_if.o br_stp_timer.o ++ ++ifeq ($(CONFIG_NETFILTER),y) ++obj-y += br_netfilter.o ++endif ++ + obj-m := $(O_TARGET) + + include $(TOPDIR)/Rules.make +diff -Nurb src/linux/linux.stock/net/bridge/br.c src/linux/linux/net/bridge/br.c +--- src/linux/linux.stock/net/bridge/br.c 2003-10-14 04:09:32.000000000 -0400 ++++ src/linux/linux/net/bridge/br.c 2004-07-10 23:46:39.000000000 -0400 +@@ -29,6 +29,8 @@ + #include "../atm/lec.h" + #endif + ++int (*br_should_route_hook) (struct sk_buff **pskb) = NULL; ++ + void br_dec_use_count() + { + MOD_DEC_USE_COUNT; +@@ -43,6 +45,10 @@ + { + printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n"); + ++#ifdef CONFIG_NETFILTER ++ if (br_netfilter_init()) ++ return 1; ++#endif + br_handle_frame_hook = br_handle_frame; + br_ioctl_hook = br_ioctl_deviceless_stub; + #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE) +@@ -61,6 +67,9 @@ + + static void __exit br_deinit(void) + { ++#ifdef CONFIG_NETFILTER ++ br_netfilter_fini(); ++#endif + unregister_netdevice_notifier(&br_device_notifier); + br_call_ioctl_atomic(__br_clear_ioctl_hook); + +@@ -74,7 +83,7 @@ + #endif + } + +-EXPORT_NO_SYMBOLS; ++EXPORT_SYMBOL(br_should_route_hook); + + module_init(br_init) + module_exit(br_deinit) +diff -Nurb src/linux/linux.stock/net/bridge/br_forward.c src/linux/linux/net/bridge/br_forward.c +--- src/linux/linux.stock/net/bridge/br_forward.c 2003-10-14 04:09:32.000000000 -0400 ++++ src/linux/linux/net/bridge/br_forward.c 2004-07-10 23:46:39.000000000 -0400 +@@ -30,18 +30,21 @@ + return 1; + } + +-static int __dev_queue_push_xmit(struct sk_buff *skb) ++int br_dev_queue_push_xmit(struct sk_buff *skb) + { ++#ifdef CONFIG_NETFILTER ++ nf_bridge_maybe_copy_header(skb); ++#endif + skb_push(skb, ETH_HLEN); + dev_queue_xmit(skb); + + return 0; + } + +-static int __br_forward_finish(struct sk_buff *skb) ++int br_forward_finish(struct sk_buff *skb) + { + NF_HOOK(PF_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev, +- __dev_queue_push_xmit); ++ br_dev_queue_push_xmit); + + return 0; + } +@@ -49,8 +52,11 @@ + static void __br_deliver(struct net_bridge_port *to, struct sk_buff *skb) + { + skb->dev = to->dev; ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug = 0; ++#endif + NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, +- __br_forward_finish); ++ br_forward_finish); + } + + static void __br_forward(struct net_bridge_port *to, struct sk_buff *skb) +@@ -61,7 +67,7 @@ + skb->dev = to->dev; + + NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev, +- __br_forward_finish); ++ br_forward_finish); + } + + /* called under bridge lock */ +diff -Nurb src/linux/linux.stock/net/bridge/br_input.c src/linux/linux/net/bridge/br_input.c +--- src/linux/linux.stock/net/bridge/br_input.c 2003-10-14 04:09:32.000000000 -0400 ++++ src/linux/linux/net/bridge/br_input.c 2004-07-10 23:48:36.000000000 -0400 +@@ -24,6 +24,9 @@ + + static int br_pass_frame_up_finish(struct sk_buff *skb) + { ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug = 0; ++#endif + netif_rx(skb); + + return 0; +@@ -46,7 +49,7 @@ + br_pass_frame_up_finish); + } + +-static int br_handle_frame_finish(struct sk_buff *skb) ++int br_handle_frame_finish(struct sk_buff *skb) + { + struct net_bridge *br; + unsigned char *dest; +@@ -112,7 +115,7 @@ + return 0; + } + +-void br_handle_frame(struct sk_buff *skb) ++int br_handle_frame(struct sk_buff *skb) + { + struct net_bridge *br; + unsigned char *dest; +@@ -146,25 +149,34 @@ + goto handle_special_frame; + + if (p->state == BR_STATE_FORWARDING) { ++ if (br_should_route_hook && br_should_route_hook(&skb)) { ++ read_unlock(&br->lock); ++ return -1; ++ } ++ ++ if (!memcmp(p->br->dev.dev_addr, dest, ETH_ALEN)) ++ skb->pkt_type = PACKET_HOST; ++ + NF_HOOK(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, + br_handle_frame_finish); + read_unlock(&br->lock); +- return; ++ return 0; + } + + err: + read_unlock(&br->lock); + err_nolock: + kfree_skb(skb); +- return; ++ return 0; + + handle_special_frame: + if (!dest[5]) { + br_stp_handle_bpdu(skb); + read_unlock(&br->lock); +- return; ++ return 0; + } + + read_unlock(&br->lock); + kfree_skb(skb); ++ return 0; + } +diff -Nurb src/linux/linux.stock/net/bridge/br_netfilter.c src/linux/linux/net/bridge/br_netfilter.c +--- src/linux/linux.stock/net/bridge/br_netfilter.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/br_netfilter.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,896 @@ ++/* ++ * Handle firewalling ++ * Linux ethernet bridge ++ * ++ * Authors: ++ * Lennert Buytenhek ++ * Bart De Schuymer (maintainer) ++ * ++ * Changes: ++ * Apr 29 2003: physdev module support (bdschuym) ++ * Jun 19 2003: let arptables see bridged ARP traffic (bdschuym) ++ * Oct 06 2003: filter encapsulated IP/ARP VLAN traffic on untagged bridge ++ * (bdschuym) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ * ++ * Lennert dedicates this file to Kerstin Wurdinger. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "br_private.h" ++#ifdef CONFIG_SYSCTL ++#include ++#endif ++ ++ ++#define skb_origaddr(skb) (((struct bridge_skb_cb *) \ ++ (skb->nf_bridge->data))->daddr.ipv4) ++#define store_orig_dstaddr(skb) (skb_origaddr(skb) = (skb)->nh.iph->daddr) ++#define dnat_took_place(skb) (skb_origaddr(skb) != (skb)->nh.iph->daddr) ++ ++#define has_bridge_parent(device) ((device)->br_port != NULL) ++#define bridge_parent(device) (&((device)->br_port->br->dev)) ++ ++#ifdef CONFIG_SYSCTL ++static struct ctl_table_header *brnf_sysctl_header; ++static int brnf_call_iptables = 1; ++static int brnf_call_arptables = 1; ++static int brnf_filter_vlan_tagged = 1; ++#else ++#define brnf_filter_vlan_tagged 1 ++#endif ++ ++#define IS_VLAN_IP (skb->protocol == __constant_htons(ETH_P_8021Q) && \ ++ hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_IP) && \ ++ brnf_filter_vlan_tagged) ++/* ++#define IS_VLAN_ARP (skb->protocol == __constant_htons(ETH_P_8021Q) && \ ++ hdr->h_vlan_encapsulated_proto == __constant_htons(ETH_P_ARP) && \ ++ brnf_filter_vlan_tagged) ++*/ ++ ++/* We need these fake structures to make netfilter happy -- ++ * lots of places assume that skb->dst != NULL, which isn't ++ * all that unreasonable. ++ * ++ * Currently, we fill in the PMTU entry because netfilter ++ * refragmentation needs it, and the rt_flags entry because ++ * ipt_REJECT needs it. Future netfilter modules might ++ * require us to fill additional fields. ++ */ ++static struct net_device __fake_net_device = { ++ .hard_header_len = ETH_HLEN ++}; ++ ++static struct rtable __fake_rtable = { ++ u: { ++ dst: { ++ __refcnt: ATOMIC_INIT(1), ++ dev: &__fake_net_device, ++ pmtu: 1500 ++ } ++ }, ++ ++ rt_flags: 0 ++}; ++ ++ ++/* PF_BRIDGE/PRE_ROUTING *********************************************/ ++static void __br_dnat_complain(void) ++{ ++ static unsigned long last_complaint; ++ ++ if (jiffies - last_complaint >= 5 * HZ) { ++ printk(KERN_WARNING "Performing cross-bridge DNAT requires IP " ++ "forwarding to be enabled\n"); ++ last_complaint = jiffies; ++ } ++} ++ ++ ++/* This requires some explaining. If DNAT has taken place, ++ * we will need to fix up the destination Ethernet address, ++ * and this is a tricky process. ++ * ++ * There are two cases to consider: ++ * 1. The packet was DNAT'ed to a device in the same bridge ++ * port group as it was received on. We can still bridge ++ * the packet. ++ * 2. The packet was DNAT'ed to a different device, either ++ * a non-bridged device or another bridge port group. ++ * The packet will need to be routed. ++ * ++ * The correct way of distinguishing between these two cases is to ++ * call ip_route_input() and to look at skb->dst->dev, which is ++ * changed to the destination device if ip_route_input() succeeds. ++ * ++ * Let us first consider the case that ip_route_input() succeeds: ++ * ++ * If skb->dst->dev equals the logical bridge device the packet ++ * came in on, we can consider this bridging. We then call ++ * skb->dst->output() which will make the packet enter br_nf_local_out() ++ * not much later. In that function it is assured that the iptables ++ * FORWARD chain is traversed for the packet. ++ * ++ * Otherwise, the packet is considered to be routed and we just ++ * change the destination MAC address so that the packet will ++ * later be passed up to the IP stack to be routed. ++ * ++ * Let us now consider the case that ip_route_input() fails: ++ * ++ * After a "echo '0' > /proc/sys/net/ipv4/ip_forward" ip_route_input() ++ * will fail, while __ip_route_output_key() will return success. The source ++ * address for __ip_route_output_key() is set to zero, so __ip_route_output_key ++ * thinks we're handling a locally generated packet and won't care ++ * if IP forwarding is allowed. We send a warning message to the users's ++ * log telling her to put IP forwarding on. ++ * ++ * ip_route_input() will also fail if there is no route available. ++ * In that case we just drop the packet. ++ * ++ * --Lennert, 20020411 ++ * --Bart, 20020416 (updated) ++ * --Bart, 20021007 (updated) ++ */ ++ ++static int br_nf_pre_routing_finish_bridge(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug |= (1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_FORWARD); ++#endif ++ ++ if (skb->pkt_type == PACKET_OTHERHOST) { ++ skb->pkt_type = PACKET_HOST; ++ skb->nf_bridge->mask |= BRNF_PKT_TYPE; ++ } ++ skb->nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; ++ ++ skb->dev = bridge_parent(skb->dev); ++ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { ++ skb_pull(skb, VLAN_HLEN); ++ skb->nh.raw += VLAN_HLEN; ++ } ++ skb->dst->output(skb); ++ return 0; ++} ++ ++static int br_nf_pre_routing_finish(struct sk_buff *skb) ++{ ++ struct net_device *dev = skb->dev; ++ struct iphdr *iph = skb->nh.iph; ++ struct nf_bridge_info *nf_bridge = skb->nf_bridge; ++ ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug ^= (1 << NF_BR_PRE_ROUTING); ++#endif ++ ++ if (nf_bridge->mask & BRNF_PKT_TYPE) { ++ skb->pkt_type = PACKET_OTHERHOST; ++ nf_bridge->mask ^= BRNF_PKT_TYPE; ++ } ++ nf_bridge->mask ^= BRNF_NF_BRIDGE_PREROUTING; ++ ++ if (dnat_took_place(skb)) { ++ if (ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, ++ dev)) { ++ struct rtable *rt; ++ ++ if (!ip_route_output(&rt, iph->daddr, 0, iph->tos, 0)) { ++ /* Bridged-and-DNAT'ed traffic doesn't ++ * require ip_forwarding. ++ */ ++ if (((struct dst_entry *)rt)->dev == dev) { ++ skb->dst = (struct dst_entry *)rt; ++ goto bridged_dnat; ++ } ++ __br_dnat_complain(); ++ dst_release((struct dst_entry *)rt); ++ } ++ kfree_skb(skb); ++ return 0; ++ } else { ++ if (skb->dst->dev == dev) { ++bridged_dnat: ++ /* Tell br_nf_local_out this is a ++ * bridged frame ++ */ ++ nf_bridge->mask |= BRNF_BRIDGED_DNAT; ++ skb->dev = nf_bridge->physindev; ++ if (skb->protocol == ++ __constant_htons(ETH_P_8021Q)) { ++ skb_push(skb, VLAN_HLEN); ++ skb->nh.raw -= VLAN_HLEN; ++ } ++ NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, ++ skb, skb->dev, NULL, ++ br_nf_pre_routing_finish_bridge, ++ 1); ++ return 0; ++ } ++ memcpy(skb->mac.ethernet->h_dest, dev->dev_addr, ++ ETH_ALEN); ++ skb->pkt_type = PACKET_HOST; ++ } ++ } else { ++ skb->dst = (struct dst_entry *)&__fake_rtable; ++ dst_hold(skb->dst); ++ } ++ ++ skb->dev = nf_bridge->physindev; ++ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { ++ skb_push(skb, VLAN_HLEN); ++ skb->nh.raw -= VLAN_HLEN; ++ } ++ NF_HOOK_THRESH(PF_BRIDGE, NF_BR_PRE_ROUTING, skb, skb->dev, NULL, ++ br_handle_frame_finish, 1); ++ ++ return 0; ++} ++ ++/* Replicate the checks that IPv4 does on packet reception. ++ * Set skb->dev to the bridge device (i.e. parent of the ++ * receiving device) to make netfilter happy, the REDIRECT ++ * target in particular. Save the original destination IP ++ * address to be able to detect DNAT afterwards. ++ */ ++static unsigned int br_nf_pre_routing(unsigned int hook, struct sk_buff **pskb, ++ const struct net_device *in, const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct iphdr *iph; ++ __u32 len; ++ struct sk_buff *skb = *pskb; ++ struct nf_bridge_info *nf_bridge; ++ ++#ifdef CONFIG_SYSCTL ++ if (!brnf_call_iptables) ++ return NF_ACCEPT; ++#endif ++ ++ if (skb->protocol != __constant_htons(ETH_P_IP)) { ++ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *) ++ ((*pskb)->mac.ethernet); ++ ++ if (!IS_VLAN_IP) ++ return NF_ACCEPT; ++ if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) ++ goto out; ++ skb_pull(*pskb, VLAN_HLEN); ++ (*pskb)->nh.raw += VLAN_HLEN; ++ } else if ((skb = skb_share_check(*pskb, GFP_ATOMIC)) == NULL) ++ goto out; ++ ++ if (!pskb_may_pull(skb, sizeof(struct iphdr))) ++ goto inhdr_error; ++ ++ iph = skb->nh.iph; ++ if (iph->ihl < 5 || iph->version != 4) ++ goto inhdr_error; ++ ++ if (!pskb_may_pull(skb, 4*iph->ihl)) ++ goto inhdr_error; ++ ++ iph = skb->nh.iph; ++ if (ip_fast_csum((__u8 *)iph, iph->ihl) != 0) ++ goto inhdr_error; ++ ++ len = ntohs(iph->tot_len); ++ if (skb->len < len || len < 4*iph->ihl) ++ goto inhdr_error; ++ ++ if (skb->len > len) { ++ __pskb_trim(skb, len); ++ if (skb->ip_summed == CHECKSUM_HW) ++ skb->ip_summed = CHECKSUM_NONE; ++ } ++ ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug ^= (1 << NF_IP_PRE_ROUTING); ++#endif ++ if ((nf_bridge = nf_bridge_alloc(skb)) == NULL) ++ return NF_DROP; ++ ++ if (skb->pkt_type == PACKET_OTHERHOST) { ++ skb->pkt_type = PACKET_HOST; ++ nf_bridge->mask |= BRNF_PKT_TYPE; ++ } ++ ++ nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING; ++ nf_bridge->physindev = skb->dev; ++ skb->dev = bridge_parent(skb->dev); ++ store_orig_dstaddr(skb); ++ ++ NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, skb->dev, NULL, ++ br_nf_pre_routing_finish); ++ ++ return NF_STOLEN; ++ ++inhdr_error: ++// IP_INC_STATS_BH(IpInHdrErrors); ++out: ++ return NF_DROP; ++} ++ ++ ++/* PF_BRIDGE/LOCAL_IN ************************************************/ ++/* The packet is locally destined, which requires a real ++ * dst_entry, so detach the fake one. On the way up, the ++ * packet would pass through PRE_ROUTING again (which already ++ * took place when the packet entered the bridge), but we ++ * register an IPv4 PRE_ROUTING 'sabotage' hook that will ++ * prevent this from happening. ++ */ ++static unsigned int br_nf_local_in(unsigned int hook, struct sk_buff **pskb, ++ const struct net_device *in, const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct sk_buff *skb = *pskb; ++ ++ if (skb->dst == (struct dst_entry *)&__fake_rtable) { ++ dst_release(skb->dst); ++ skb->dst = NULL; ++ } ++ ++ return NF_ACCEPT; ++} ++ ++/* PF_BRIDGE/FORWARD *************************************************/ ++static int br_nf_forward_finish(struct sk_buff *skb) ++{ ++ struct nf_bridge_info *nf_bridge = skb->nf_bridge; ++ struct net_device *in; ++ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); ++ ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug ^= (1 << NF_BR_FORWARD); ++#endif ++ ++ if (skb->protocol == __constant_htons(ETH_P_IP) || IS_VLAN_IP) { ++ in = nf_bridge->physindev; ++ if (nf_bridge->mask & BRNF_PKT_TYPE) { ++ skb->pkt_type = PACKET_OTHERHOST; ++ nf_bridge->mask ^= BRNF_PKT_TYPE; ++ } ++ } else { ++ in = *((struct net_device **)(skb->cb)); ++ } ++ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { ++ skb_push(skb, VLAN_HLEN); ++ skb->nh.raw -= VLAN_HLEN; ++ } ++ NF_HOOK_THRESH(PF_BRIDGE, NF_BR_FORWARD, skb, in, ++ skb->dev, br_forward_finish, 1); ++ return 0; ++} ++ ++/* This is the 'purely bridged' case. For IP, we pass the packet to ++ * netfilter with indev and outdev set to the bridge device, ++ * but we are still able to filter on the 'real' indev/outdev ++ * because of the ipt_physdev.c module. For ARP, indev and outdev are the ++ * bridge ports. ++ */ ++static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff **pskb, ++ const struct net_device *in, const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct sk_buff *skb = *pskb; ++ struct nf_bridge_info *nf_bridge; ++ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); ++ ++#ifdef CONFIG_SYSCTL ++ if (!skb->nf_bridge) ++ return NF_ACCEPT; ++#endif ++ ++ if (skb->protocol != __constant_htons(ETH_P_IP)) { ++ if (!IS_VLAN_IP) ++ return NF_ACCEPT; ++ skb_pull(*pskb, VLAN_HLEN); ++ (*pskb)->nh.raw += VLAN_HLEN; ++ } ++ ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug ^= (1 << NF_BR_FORWARD); ++#endif ++ nf_bridge = skb->nf_bridge; ++ if (skb->pkt_type == PACKET_OTHERHOST) { ++ skb->pkt_type = PACKET_HOST; ++ nf_bridge->mask |= BRNF_PKT_TYPE; ++ } ++ ++ /* The physdev module checks on this */ ++ nf_bridge->mask |= BRNF_BRIDGED; ++ nf_bridge->physoutdev = skb->dev; ++ ++ NF_HOOK(PF_INET, NF_IP_FORWARD, skb, bridge_parent(in), ++ bridge_parent(out), br_nf_forward_finish); ++ ++ return NF_STOLEN; ++} ++ ++/* ++static unsigned int br_nf_forward_arp(unsigned int hook, struct sk_buff **pskb, ++ const struct net_device *in, const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct sk_buff *skb = *pskb; ++ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); ++ struct net_device **d = (struct net_device **)(skb->cb); ++ ++ if (!brnf_call_arptables) ++ return NF_ACCEPT; ++ ++ if (skb->protocol != __constant_htons(ETH_P_ARP)) { ++ if (!IS_VLAN_ARP) ++ return NF_ACCEPT; ++ skb_pull(*pskb, VLAN_HLEN); ++ (*pskb)->nh.raw += VLAN_HLEN; ++ } ++ ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug ^= (1 << NF_BR_FORWARD); ++#endif ++ ++ if (skb->nh.arph->ar_pln != 4) { ++ if (IS_VLAN_ARP) { ++ skb_push(*pskb, VLAN_HLEN); ++ (*pskb)->nh.raw -= VLAN_HLEN; ++ } ++ return NF_ACCEPT; ++ } ++ *d = (struct net_device *)in; ++ NF_HOOK(NF_ARP, NF_ARP_FORWARD, skb, (struct net_device *)in, ++ (struct net_device *)out, br_nf_forward_finish); ++ ++ return NF_STOLEN; ++} ++*/ ++ ++/* PF_BRIDGE/LOCAL_OUT ***********************************************/ ++static int br_nf_local_out_finish(struct sk_buff *skb) ++{ ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug &= ~(1 << NF_BR_LOCAL_OUT); ++#endif ++ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { ++ skb_push(skb, VLAN_HLEN); ++ skb->nh.raw -= VLAN_HLEN; ++ } ++ ++ NF_HOOK_THRESH(PF_BRIDGE, NF_BR_LOCAL_OUT, skb, NULL, skb->dev, ++ br_forward_finish, NF_BR_PRI_FIRST + 1); ++ ++ return 0; ++} ++ ++ ++/* This function sees both locally originated IP packets and forwarded ++ * IP packets (in both cases the destination device is a bridge ++ * device). It also sees bridged-and-DNAT'ed packets. ++ * To be able to filter on the physical bridge devices (with the ipt_physdev.c ++ * module), we steal packets destined to a bridge device away from the ++ * PF_INET/FORWARD and PF_INET/OUTPUT hook functions, and give them back later, ++ * when we have determined the real output device. This is done in here. ++ * ++ * If (nf_bridge->mask & BRNF_BRIDGED_DNAT) then the packet is bridged ++ * and we fake the PF_BRIDGE/FORWARD hook. The function br_nf_forward() ++ * will then fake the PF_INET/FORWARD hook. br_nf_local_out() has priority ++ * NF_BR_PRI_FIRST, so no relevant PF_BRIDGE/INPUT functions have been nor ++ * will be executed. ++ * Otherwise, if nf_bridge->physindev is NULL, the bridge-nf code never touched ++ * this packet before, and so the packet was locally originated. We fake ++ * the PF_INET/LOCAL_OUT hook. ++ * Finally, if nf_bridge->physindev isn't NULL, then the packet was IP routed, ++ * so we fake the PF_INET/FORWARD hook. ipv4_sabotage_out() makes sure ++ * even routed packets that didn't arrive on a bridge interface have their ++ * nf_bridge->physindev set. ++ */ ++ ++static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff **pskb, ++ const struct net_device *in, const struct net_device *out, ++ int (*_okfn)(struct sk_buff *)) ++{ ++ int (*okfn)(struct sk_buff *skb); ++ struct net_device *realindev; ++ struct sk_buff *skb = *pskb; ++ struct nf_bridge_info *nf_bridge; ++ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); ++ ++#ifdef CONFIG_SYSCTL ++ if (!skb->nf_bridge) ++ return NF_ACCEPT; ++#endif ++ ++ if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP) ++ return NF_ACCEPT; ++ ++ /* Sometimes we get packets with NULL ->dst here (for example, ++ * running a dhcp client daemon triggers this). ++ */ ++ if (skb->dst == NULL) ++ return NF_ACCEPT; ++ ++ nf_bridge = skb->nf_bridge; ++ nf_bridge->physoutdev = skb->dev; ++ realindev = nf_bridge->physindev; ++ ++ /* Bridged, take PF_BRIDGE/FORWARD. ++ * (see big note in front of br_nf_pre_routing_finish) ++ */ ++ if (nf_bridge->mask & BRNF_BRIDGED_DNAT) { ++ okfn = br_forward_finish; ++ ++ if (nf_bridge->mask & BRNF_PKT_TYPE) { ++ skb->pkt_type = PACKET_OTHERHOST; ++ nf_bridge->mask ^= BRNF_PKT_TYPE; ++ } ++ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { ++ skb_push(skb, VLAN_HLEN); ++ skb->nh.raw -= VLAN_HLEN; ++ } ++ ++ NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, realindev, ++ skb->dev, okfn); ++ } else { ++ struct net_device *realoutdev = bridge_parent(skb->dev); ++ ++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) ++ /* iptables should match -o br0.x */ ++ if (nf_bridge->netoutdev) ++ realoutdev = nf_bridge->netoutdev; ++#endif ++ okfn = br_nf_local_out_finish; ++ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { ++ skb_pull(skb, VLAN_HLEN); ++ (*pskb)->nh.raw += VLAN_HLEN; ++ } ++ /* IP forwarded traffic has a physindev, locally ++ * generated traffic hasn't. ++ */ ++ if (realindev != NULL) { ++ if (((nf_bridge->mask & BRNF_DONT_TAKE_PARENT) == 0) && ++ has_bridge_parent(realindev)) ++ realindev = bridge_parent(realindev); ++ NF_HOOK_THRESH(PF_INET, NF_IP_FORWARD, skb, realindev, ++ realoutdev, okfn, ++ NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD + 1); ++ } else { ++#ifdef CONFIG_NETFILTER_DEBUG ++ skb->nf_debug ^= (1 << NF_IP_LOCAL_OUT); ++#endif ++ ++ NF_HOOK_THRESH(PF_INET, NF_IP_LOCAL_OUT, skb, realindev, ++ realoutdev, okfn, ++ NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT + 1); ++ } ++ } ++ ++ return NF_STOLEN; ++} ++ ++ ++/* PF_BRIDGE/POST_ROUTING ********************************************/ ++static unsigned int br_nf_post_routing(unsigned int hook, struct sk_buff **pskb, ++ const struct net_device *in, const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct sk_buff *skb = *pskb; ++ struct nf_bridge_info *nf_bridge = (*pskb)->nf_bridge; ++ struct vlan_ethhdr *hdr = (struct vlan_ethhdr *)(skb->mac.ethernet); ++ struct net_device *realoutdev = bridge_parent(skb->dev); ++ ++#ifdef CONFIG_NETFILTER_DEBUG ++ /* Be very paranoid. This probably won't happen anymore, but let's ++ * keep the check just to be sure... */ ++ if (skb->mac.raw < skb->head || skb->mac.raw + ETH_HLEN > skb->data) { ++ printk(KERN_CRIT "br_netfilter: Argh!! br_nf_post_routing: " ++ "bad mac.raw pointer."); ++ goto print_error; ++ } ++#endif ++ ++#ifdef CONFIG_SYSCTL ++ if (!nf_bridge) ++ return NF_ACCEPT; ++#endif ++ ++ if (skb->protocol != __constant_htons(ETH_P_IP) && !IS_VLAN_IP) ++ return NF_ACCEPT; ++ ++ /* Sometimes we get packets with NULL ->dst here (for example, ++ * running a dhcp client daemon triggers this). ++ */ ++ if (skb->dst == NULL) ++ return NF_ACCEPT; ++ ++#ifdef CONFIG_NETFILTER_DEBUG ++ /* Sometimes we get packets with NULL ->dst here (for example, ++ * running a dhcp client daemon triggers this). This should now ++ * be fixed, but let's keep the check around. ++ */ ++ if (skb->dst == NULL) { ++ printk(KERN_CRIT "br_netfilter: skb->dst == NULL."); ++ goto print_error; ++ } ++ ++ skb->nf_debug ^= (1 << NF_IP_POST_ROUTING); ++#endif ++ ++ /* We assume any code from br_dev_queue_push_xmit onwards doesn't care ++ * about the value of skb->pkt_type. ++ */ ++ if (skb->pkt_type == PACKET_OTHERHOST) { ++ skb->pkt_type = PACKET_HOST; ++ nf_bridge->mask |= BRNF_PKT_TYPE; ++ } ++ ++ if (skb->protocol == __constant_htons(ETH_P_8021Q)) { ++ skb_pull(skb, VLAN_HLEN); ++ skb->nh.raw += VLAN_HLEN; ++ } ++ ++ nf_bridge_save_header(skb); ++ ++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) ++ if (nf_bridge->netoutdev) ++ realoutdev = nf_bridge->netoutdev; ++#endif ++ NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, ++ realoutdev, br_dev_queue_push_xmit); ++ ++ return NF_STOLEN; ++ ++#ifdef CONFIG_NETFILTER_DEBUG ++print_error: ++ if (skb->dev != NULL) { ++ printk("[%s]", skb->dev->name); ++ if (has_bridge_parent(skb->dev)) ++ printk("[%s]", bridge_parent(skb->dev)->name); ++ } ++ printk(" head:%p, raw:%p, data:%p\n", skb->head, skb->mac.raw, ++ skb->data); ++ return NF_ACCEPT; ++#endif ++} ++ ++ ++/* IPv4/SABOTAGE *****************************************************/ ++ ++/* Don't hand locally destined packets to PF_INET/PRE_ROUTING ++ * for the second time. ++ */ ++static unsigned int ipv4_sabotage_in(unsigned int hook, struct sk_buff **pskb, ++ const struct net_device *in, const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ if ((*pskb)->nf_bridge && ++ !((*pskb)->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) { ++ okfn(*pskb); ++ return NF_STOLEN; ++ } ++ ++ return NF_ACCEPT; ++} ++ ++/* Postpone execution of PF_INET/FORWARD, PF_INET/LOCAL_OUT ++ * and PF_INET/POST_ROUTING until we have done the forwarding ++ * decision in the bridge code and have determined skb->physoutdev. ++ */ ++static unsigned int ipv4_sabotage_out(unsigned int hook, struct sk_buff **pskb, ++ const struct net_device *in, const struct net_device *out, ++ int (*okfn)(struct sk_buff *)) ++{ ++ struct sk_buff *skb = *pskb; ++ ++#ifdef CONFIG_SYSCTL ++ if (!brnf_call_iptables && !skb->nf_bridge) ++ return NF_ACCEPT; ++#endif ++ ++ if ((out->hard_start_xmit == br_dev_xmit && ++ okfn != br_nf_forward_finish && ++ okfn != br_nf_local_out_finish && ++ okfn != br_dev_queue_push_xmit) ++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) ++ || ((out->priv_flags & IFF_802_1Q_VLAN) && ++ VLAN_DEV_INFO(out)->real_dev->hard_start_xmit == br_dev_xmit) ++#endif ++ ) { ++ struct nf_bridge_info *nf_bridge; ++ ++ if (!skb->nf_bridge && !nf_bridge_alloc(skb)) ++ return NF_DROP; ++ ++ nf_bridge = skb->nf_bridge; ++ ++ /* This frame will arrive on PF_BRIDGE/LOCAL_OUT and we ++ * will need the indev then. For a brouter, the real indev ++ * can be a bridge port, so we make sure br_nf_local_out() ++ * doesn't use the bridge parent of the indev by using ++ * the BRNF_DONT_TAKE_PARENT mask. ++ */ ++ if (hook == NF_IP_FORWARD && nf_bridge->physindev == NULL) { ++ nf_bridge->mask &= BRNF_DONT_TAKE_PARENT; ++ nf_bridge->physindev = (struct net_device *)in; ++ } ++#if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) ++ /* the iptables outdev is br0.x, not br0 */ ++ if (out->priv_flags & IFF_802_1Q_VLAN) ++ nf_bridge->netoutdev = (struct net_device *)out; ++#endif ++ okfn(skb); ++ return NF_STOLEN; ++ } ++ ++ return NF_ACCEPT; ++} ++ ++/* For br_nf_local_out we need (prio = NF_BR_PRI_FIRST), to insure that innocent ++ * PF_BRIDGE/NF_BR_LOCAL_OUT functions don't get bridged traffic as input. ++ * For br_nf_post_routing, we need (prio = NF_BR_PRI_LAST), because ++ * ip_refrag() can return NF_STOLEN. ++ */ ++static struct nf_hook_ops br_nf_ops[] = { ++ { .hook = br_nf_pre_routing, ++ .pf = PF_BRIDGE, ++ .hooknum = NF_BR_PRE_ROUTING, ++ .priority = NF_BR_PRI_BRNF, }, ++ { .hook = br_nf_local_in, ++ .pf = PF_BRIDGE, ++ .hooknum = NF_BR_LOCAL_IN, ++ .priority = NF_BR_PRI_BRNF, }, ++ { .hook = br_nf_forward_ip, ++ .pf = PF_BRIDGE, ++ .hooknum = NF_BR_FORWARD, ++ .priority = NF_BR_PRI_BRNF /*- 1*/, }, ++/* { .hook = br_nf_forward_arp, ++ .pf = PF_BRIDGE, ++ .hooknum = NF_BR_FORWARD, ++ .priority = NF_BR_PRI_BRNF, },*/ ++ { .hook = br_nf_local_out, ++ .pf = PF_BRIDGE, ++ .hooknum = NF_BR_LOCAL_OUT, ++ .priority = NF_BR_PRI_FIRST, }, ++ { .hook = br_nf_post_routing, ++ .pf = PF_BRIDGE, ++ .hooknum = NF_BR_POST_ROUTING, ++ .priority = NF_BR_PRI_LAST, }, ++ { .hook = ipv4_sabotage_in, ++ .pf = PF_INET, ++ .hooknum = NF_IP_PRE_ROUTING, ++ .priority = NF_IP_PRI_FIRST, }, ++ { .hook = ipv4_sabotage_out, ++ .pf = PF_INET, ++ .hooknum = NF_IP_FORWARD, ++ .priority = NF_IP_PRI_BRIDGE_SABOTAGE_FORWARD, }, ++ { .hook = ipv4_sabotage_out, ++ .pf = PF_INET, ++ .hooknum = NF_IP_LOCAL_OUT, ++ .priority = NF_IP_PRI_BRIDGE_SABOTAGE_LOCAL_OUT, }, ++ { .hook = ipv4_sabotage_out, ++ .pf = PF_INET, ++ .hooknum = NF_IP_POST_ROUTING, ++ .priority = NF_IP_PRI_FIRST, }, ++}; ++ ++#ifdef CONFIG_SYSCTL ++static ++int brnf_sysctl_call_tables(ctl_table *ctl, int write, struct file * filp, ++ void *buffer, size_t *lenp) ++{ ++ int ret; ++ ++ ret = proc_dointvec(ctl, write, filp, buffer, lenp); ++ ++ if (write && *(int *)(ctl->data)) ++ *(int *)(ctl->data) = 1; ++ return ret; ++} ++ ++static ctl_table brnf_table[] = { ++ { ++ .ctl_name = NET_BRIDGE_NF_CALL_ARPTABLES, ++ .procname = "bridge-nf-call-arptables", ++ .data = &brnf_call_arptables, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = &brnf_sysctl_call_tables, ++ }, ++ { ++ .ctl_name = NET_BRIDGE_NF_CALL_IPTABLES, ++ .procname = "bridge-nf-call-iptables", ++ .data = &brnf_call_iptables, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = &brnf_sysctl_call_tables, ++ }, ++ { ++ .ctl_name = NET_BRIDGE_NF_FILTER_VLAN_TAGGED, ++ .procname = "bridge-nf-filter-vlan-tagged", ++ .data = &brnf_filter_vlan_tagged, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = &brnf_sysctl_call_tables, ++ }, ++ { .ctl_name = 0 } ++}; ++ ++static ctl_table brnf_bridge_table[] = { ++ { ++ .ctl_name = NET_BRIDGE, ++ .procname = "bridge", ++ .mode = 0555, ++ .child = brnf_table, ++ }, ++ { .ctl_name = 0 } ++}; ++ ++static ctl_table brnf_net_table[] = { ++ { ++ .ctl_name = CTL_NET, ++ .procname = "net", ++ .mode = 0555, ++ .child = brnf_bridge_table, ++ }, ++ { .ctl_name = 0 } ++}; ++#endif ++ ++int br_netfilter_init(void) ++{ ++ int i; ++ ++ for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) { ++ int ret; ++ ++ if ((ret = nf_register_hook(&br_nf_ops[i])) >= 0) ++ continue; ++ ++ while (i--) ++ nf_unregister_hook(&br_nf_ops[i]); ++ ++ return ret; ++ } ++ ++#ifdef CONFIG_SYSCTL ++ brnf_sysctl_header = register_sysctl_table(brnf_net_table, 0); ++ if (brnf_sysctl_header == NULL) { ++ printk(KERN_WARNING "br_netfilter: can't register to sysctl.\n"); ++ for (i = 0; i < ARRAY_SIZE(br_nf_ops); i++) ++ nf_unregister_hook(&br_nf_ops[i]); ++ return -EFAULT; ++ } ++#endif ++ ++ printk(KERN_NOTICE "Bridge firewalling registered\n"); ++ ++ return 0; ++} ++ ++void br_netfilter_fini(void) ++{ ++ int i; ++ ++ for (i = ARRAY_SIZE(br_nf_ops) - 1; i >= 0; i--) ++ nf_unregister_hook(&br_nf_ops[i]); ++#ifdef CONFIG_SYSCTL ++ unregister_sysctl_table(brnf_sysctl_header); ++#endif ++ ++} +diff -Nurb src/linux/linux.stock/net/bridge/br_private.h src/linux/linux/net/bridge/br_private.h +--- src/linux/linux.stock/net/bridge/br_private.h 2003-10-14 04:09:32.000000000 -0400 ++++ src/linux/linux/net/bridge/br_private.h 2004-07-10 23:46:39.000000000 -0400 +@@ -145,8 +145,10 @@ + /* br_forward.c */ + extern void br_deliver(struct net_bridge_port *to, + struct sk_buff *skb); ++extern int br_dev_queue_push_xmit(struct sk_buff *skb); + extern void br_forward(struct net_bridge_port *to, + struct sk_buff *skb); ++extern int br_forward_finish(struct sk_buff *skb); + extern void br_flood_deliver(struct net_bridge *br, + struct sk_buff *skb, + int clone); +@@ -167,7 +169,8 @@ + int *ifindices); + + /* br_input.c */ +-extern void br_handle_frame(struct sk_buff *skb); ++extern int br_handle_frame_finish(struct sk_buff *skb); ++extern int br_handle_frame(struct sk_buff *skb); + + /* br_ioctl.c */ + extern void br_call_ioctl_atomic(void (*fn)(void)); +@@ -178,6 +181,10 @@ + unsigned long arg2); + extern int br_ioctl_deviceless_stub(unsigned long arg); + ++/* br_netfilter.c */ ++extern int br_netfilter_init(void); ++extern void br_netfilter_fini(void); ++ + /* br_stp.c */ + extern int br_is_root_bridge(struct net_bridge *br); + extern struct net_bridge_port *br_get_port(struct net_bridge *br, +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/Config.in src/linux/linux/net/bridge/netfilter/Config.in +--- src/linux/linux.stock/net/bridge/netfilter/Config.in 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/Config.in 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,22 @@ ++# ++# Bridge netfilter configuration ++# ++dep_tristate ' Bridge: ebtables' CONFIG_BRIDGE_NF_EBTABLES $CONFIG_BRIDGE ++dep_tristate ' ebt: filter table support' CONFIG_BRIDGE_EBT_T_FILTER $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: nat table support' CONFIG_BRIDGE_EBT_T_NAT $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: broute table support' CONFIG_BRIDGE_EBT_BROUTE $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: log support' CONFIG_BRIDGE_EBT_LOG $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: IP filter support' CONFIG_BRIDGE_EBT_IPF $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: ARP filter support' CONFIG_BRIDGE_EBT_ARPF $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: among filter support' CONFIG_BRIDGE_EBT_AMONG $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: limit filter support' CONFIG_BRIDGE_EBT_LIMIT $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: 802.1Q VLAN filter support' CONFIG_BRIDGE_EBT_VLANF $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: 802.3 filter support' CONFIG_BRIDGE_EBT_802_3 $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: packet type filter support' CONFIG_BRIDGE_EBT_PKTTYPE $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: STP filter support' CONFIG_BRIDGE_EBT_STP $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: mark filter support' CONFIG_BRIDGE_EBT_MARKF $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: arp reply target support' CONFIG_BRIDGE_EBT_ARPREPLY $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: snat target support' CONFIG_BRIDGE_EBT_SNAT $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: dnat target support' CONFIG_BRIDGE_EBT_DNAT $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: redirect target support' CONFIG_BRIDGE_EBT_REDIRECT $CONFIG_BRIDGE_NF_EBTABLES ++dep_tristate ' ebt: mark target support' CONFIG_BRIDGE_EBT_MARK_T $CONFIG_BRIDGE_NF_EBTABLES +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/Makefile src/linux/linux/net/bridge/netfilter/Makefile +--- src/linux/linux.stock/net/bridge/netfilter/Makefile 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/Makefile 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,33 @@ ++# ++# Makefile for the netfilter modules on top of bridging. ++# ++# Note! Dependencies are done automagically by 'make dep', which also ++# removes any old dependencies. DON'T put your own dependencies here ++# unless it's something special (ie not a .c file). ++# ++# Note 2! The CFLAGS definition is now in the main makefile... ++ ++O_TARGET := netfilter.o ++ ++export-objs := ebtables.o ++ ++obj-$(CONFIG_BRIDGE_NF_EBTABLES) += ebtables.o ++obj-$(CONFIG_BRIDGE_EBT_T_FILTER) += ebtable_filter.o ++obj-$(CONFIG_BRIDGE_EBT_T_NAT) += ebtable_nat.o ++obj-$(CONFIG_BRIDGE_EBT_BROUTE) += ebtable_broute.o ++obj-$(CONFIG_BRIDGE_EBT_802_3) += ebt_802_3.o ++obj-$(CONFIG_BRIDGE_EBT_ARPF) += ebt_arp.o ++obj-$(CONFIG_BRIDGE_EBT_AMONG) += ebt_among.o ++obj-$(CONFIG_BRIDGE_EBT_IPF) += ebt_ip.o ++obj-$(CONFIG_BRIDGE_EBT_LIMIT) += ebt_limit.o ++obj-$(CONFIG_BRIDGE_EBT_MARKF) += ebt_mark_m.o ++obj-$(CONFIG_BRIDGE_EBT_PKTTYPE) += ebt_pkttype.o ++obj-$(CONFIG_BRIDGE_EBT_STP) += ebt_stp.o ++obj-$(CONFIG_BRIDGE_EBT_VLANF) += ebt_vlan.o ++obj-$(CONFIG_BRIDGE_EBT_LOG) += ebt_log.o ++obj-$(CONFIG_BRIDGE_EBT_ARPREPLY) += ebt_arpreply.o ++obj-$(CONFIG_BRIDGE_EBT_DNAT) += ebt_dnat.o ++obj-$(CONFIG_BRIDGE_EBT_MARK_T) += ebt_mark.o ++obj-$(CONFIG_BRIDGE_EBT_REDIRECT) += ebt_redirect.o ++obj-$(CONFIG_BRIDGE_EBT_SNAT) += ebt_snat.o ++include $(TOPDIR)/Rules.make +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_802_3.c src/linux/linux/net/bridge/netfilter/ebt_802_3.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_802_3.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_802_3.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,74 @@ ++/* ++ * 802_3 ++ * ++ * Author: ++ * Chris Vitale csv@bluetail.com ++ * ++ * May 2003 ++ * ++ */ ++ ++#include ++#include ++#include ++ ++static int ebt_filter_802_3(const struct sk_buff *skb, const struct net_device *in, ++ const struct net_device *out, const void *data, unsigned int datalen) ++{ ++ struct ebt_802_3_info *info = (struct ebt_802_3_info *)data; ++ struct ebt_802_3_hdr *hdr = (struct ebt_802_3_hdr *)skb->mac.ethernet; ++ uint16_t type = hdr->llc.ui.ctrl & IS_UI ? hdr->llc.ui.type : hdr->llc.ni.type; ++ ++ if (info->bitmask & EBT_802_3_SAP) { ++ if (FWINV(info->sap != hdr->llc.ui.ssap, EBT_802_3_SAP)) ++ return EBT_NOMATCH; ++ if (FWINV(info->sap != hdr->llc.ui.dsap, EBT_802_3_SAP)) ++ return EBT_NOMATCH; ++ } ++ ++ if (info->bitmask & EBT_802_3_TYPE) { ++ if (!(hdr->llc.ui.dsap == CHECK_TYPE && hdr->llc.ui.ssap == CHECK_TYPE)) ++ return EBT_NOMATCH; ++ if (FWINV(info->type != type, EBT_802_3_TYPE)) ++ return EBT_NOMATCH; ++ } ++ ++ return EBT_MATCH; ++} ++ ++static struct ebt_match filter_802_3; ++static int ebt_802_3_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_802_3_info *info = (struct ebt_802_3_info *)data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_802_3_info))) ++ return -EINVAL; ++ if (info->bitmask & ~EBT_802_3_MASK || info->invflags & ~EBT_802_3_MASK) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static struct ebt_match filter_802_3 = ++{ ++ .name = EBT_802_3_MATCH, ++ .match = ebt_filter_802_3, ++ .check = ebt_802_3_check, ++ .me = THIS_MODULE, ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_match(&filter_802_3); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_match(&filter_802_3); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_among.c src/linux/linux/net/bridge/netfilter/ebt_among.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_among.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_among.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,223 @@ ++/* ++ * ebt_among ++ * ++ * Authors: ++ * Grzegorz Borowiak ++ * ++ * August, 2003 ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int ebt_mac_wormhash_contains(const struct ebt_mac_wormhash *wh, ++ const char *mac, uint32_t ip) ++{ ++ /* You may be puzzled as to how this code works. ++ * Some tricks were used, refer to ++ * include/linux/netfilter_bridge/ebt_among.h ++ * as there you can find a solution of this mystery. ++ */ ++ const struct ebt_mac_wormhash_tuple *p; ++ int start, limit, i; ++ uint32_t cmp[2] = { 0, 0 }; ++ int key = (const unsigned char) mac[5]; ++ ++ memcpy(((char *) cmp) + 2, mac, 6); ++ start = wh->table[key]; ++ limit = wh->table[key + 1]; ++ if (ip) { ++ for (i = start; i < limit; i++) { ++ p = &wh->pool[i]; ++ if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { ++ if (p->ip == 0 || p->ip == ip) { ++ return 1; ++ } ++ } ++ } ++ } else { ++ for (i = start; i < limit; i++) { ++ p = &wh->pool[i]; ++ if (cmp[1] == p->cmp[1] && cmp[0] == p->cmp[0]) { ++ if (p->ip == 0) { ++ return 1; ++ } ++ } ++ } ++ } ++ return 0; ++} ++ ++static int ebt_mac_wormhash_check_integrity(const struct ebt_mac_wormhash ++ *wh) ++{ ++ int i; ++ ++ for (i = 0; i < 256; i++) { ++ if (wh->table[i] > wh->table[i + 1]) ++ return -0x100 - i; ++ if (wh->table[i] < 0) ++ return -0x200 - i; ++ if (wh->table[i] > wh->poolsize) ++ return -0x300 - i; ++ } ++ if (wh->table[256] > wh->poolsize) ++ return -0xc00; ++ return 0; ++} ++ ++static int get_ip_dst(const struct sk_buff *skb, uint32_t * addr) ++{ ++ if (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_IP)) ++ *addr = skb->nh.iph->daddr; ++ else if (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_ARP)) { ++ uint32_t arp_len = sizeof(struct arphdr) + ++ (2 * (((*skb).nh.arph)->ar_hln)) + ++ (2 * (((*skb).nh.arph)->ar_pln)); ++ ++ /* Make sure the packet is long enough. */ ++ if ((((*skb).nh.raw) + arp_len) > (*skb).tail) ++ return -1; ++ /* IPv4 addresses are always 4 bytes. */ ++ if (((*skb).nh.arph)->ar_pln != sizeof(uint32_t)) ++ return -1; ++ ++ memcpy(addr, ((*skb).nh.raw) + sizeof(struct arphdr) + ++ (2 * (((*skb).nh.arph)->ar_hln)) + ++ (((*skb).nh.arph)->ar_pln), sizeof(uint32_t)); ++ ++ } ++ return 0; ++} ++ ++static int get_ip_src(const struct sk_buff *skb, uint32_t * addr) ++{ ++ if (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_IP)) ++ *addr = skb->nh.iph->saddr; ++ else if (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_ARP)) { ++ uint32_t arp_len = sizeof(struct arphdr) + ++ (2 * (((*skb).nh.arph)->ar_hln)) + ++ (2 * (((*skb).nh.arph)->ar_pln)); ++ ++ /* Make sure the packet is long enough. */ ++ if ((((*skb).nh.raw) + arp_len) > (*skb).tail) ++ return -1; ++ /* IPv4 addresses are always 4 bytes. */ ++ if (((*skb).nh.arph)->ar_pln != sizeof(uint32_t)) ++ return -1; ++ ++ memcpy(addr, ((*skb).nh.raw) + sizeof(struct arphdr) + ++ ((((*skb).nh.arph)->ar_hln)), sizeof(uint32_t)); ++ ++ } ++ return 0; ++} ++ ++static int ebt_filter_among(const struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, const void *data, ++ unsigned int datalen) ++{ ++ struct ebt_among_info *info = (struct ebt_among_info *) data; ++ const char *dmac, *smac; ++ const struct ebt_mac_wormhash *wh_dst, *wh_src; ++ uint32_t dip = 0, sip = 0; ++ ++ wh_dst = ebt_among_wh_dst(info); ++ wh_src = ebt_among_wh_src(info); ++ ++ if (wh_src) { ++ smac = skb->mac.ethernet->h_source; ++ if (get_ip_src(skb, &sip)) ++ return EBT_NOMATCH; ++ if (!(info->bitmask & EBT_AMONG_SRC_NEG)) { ++ /* we match only if it contains */ ++ if (!ebt_mac_wormhash_contains(wh_src, smac, sip)) ++ return EBT_NOMATCH; ++ } else { ++ /* we match only if it DOES NOT contain */ ++ if (ebt_mac_wormhash_contains(wh_src, smac, sip)) ++ return EBT_NOMATCH; ++ } ++ } ++ ++ if (wh_dst) { ++ dmac = skb->mac.ethernet->h_dest; ++ if (get_ip_dst(skb, &dip)) ++ return EBT_NOMATCH; ++ if (!(info->bitmask & EBT_AMONG_DST_NEG)) { ++ /* we match only if it contains */ ++ if (!ebt_mac_wormhash_contains(wh_dst, dmac, dip)) ++ return EBT_NOMATCH; ++ } else { ++ /* we match only if it DOES NOT contain */ ++ if (ebt_mac_wormhash_contains(wh_dst, dmac, dip)) ++ return EBT_NOMATCH; ++ } ++ } ++ ++ return EBT_MATCH; ++} ++ ++static int ebt_among_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, ++ unsigned int datalen) ++{ ++ struct ebt_among_info *info = (struct ebt_among_info *) data; ++ int expected_length = sizeof(struct ebt_among_info); ++ const struct ebt_mac_wormhash *wh_dst, *wh_src; ++ int err; ++ ++ wh_dst = ebt_among_wh_dst(info); ++ wh_src = ebt_among_wh_src(info); ++ expected_length += ebt_mac_wormhash_size(wh_dst); ++ expected_length += ebt_mac_wormhash_size(wh_src); ++ ++ if (datalen != EBT_ALIGN(expected_length)) { ++ printk(KERN_WARNING ++ "ebtables: among: wrong size: %d" ++ "against expected %d, rounded to %d\n", ++ datalen, expected_length, ++ EBT_ALIGN(expected_length)); ++ return -EINVAL; ++ } ++ if (wh_dst && (err = ebt_mac_wormhash_check_integrity(wh_dst))) { ++ printk(KERN_WARNING ++ "ebtables: among: dst integrity fail: %x\n", -err); ++ return -EINVAL; ++ } ++ if (wh_src && (err = ebt_mac_wormhash_check_integrity(wh_src))) { ++ printk(KERN_WARNING ++ "ebtables: among: src integrity fail: %x\n", -err); ++ return -EINVAL; ++ } ++ return 0; ++} ++ ++static struct ebt_match filter_among = { ++ {NULL, NULL}, ++ EBT_AMONG_MATCH, ++ ebt_filter_among, ++ ebt_among_check, ++ NULL, ++ THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_match(&filter_among); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_match(&filter_among); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_arp.c src/linux/linux/net/bridge/netfilter/ebt_arp.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_arp.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_arp.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,149 @@ ++/* ++ * ebt_arp ++ * ++ * Authors: ++ * Bart De Schuymer ++ * Tim Gardner ++ * ++ * April, 2002 ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int ebt_filter_arp(const struct sk_buff *skb, const struct net_device *in, ++ const struct net_device *out, const void *data, unsigned int datalen) ++{ ++ struct ebt_arp_info *info = (struct ebt_arp_info *)data; ++ ++ if (info->bitmask & EBT_ARP_OPCODE && FWINV(info->opcode != ++ ((*skb).nh.arph)->ar_op, EBT_ARP_OPCODE)) ++ return EBT_NOMATCH; ++ if (info->bitmask & EBT_ARP_HTYPE && FWINV(info->htype != ++ ((*skb).nh.arph)->ar_hrd, EBT_ARP_HTYPE)) ++ return EBT_NOMATCH; ++ if (info->bitmask & EBT_ARP_PTYPE && FWINV(info->ptype != ++ ((*skb).nh.arph)->ar_pro, EBT_ARP_PTYPE)) ++ return EBT_NOMATCH; ++ ++ if (info->bitmask & (EBT_ARP_SRC_IP | EBT_ARP_DST_IP)) ++ { ++ uint32_t arp_len = sizeof(struct arphdr) + ++ (2 * (((*skb).nh.arph)->ar_hln)) + ++ (2 * (((*skb).nh.arph)->ar_pln)); ++ uint32_t dst; ++ uint32_t src; ++ ++ // Make sure the packet is long enough. ++ if ((((*skb).nh.raw) + arp_len) > (*skb).tail) ++ return EBT_NOMATCH; ++ // IPv4 addresses are always 4 bytes. ++ if (((*skb).nh.arph)->ar_pln != sizeof(uint32_t)) ++ return EBT_NOMATCH; ++ ++ if (info->bitmask & EBT_ARP_SRC_IP) { ++ memcpy(&src, ((*skb).nh.raw) + sizeof(struct arphdr) + ++ ((*skb).nh.arph)->ar_hln, sizeof(uint32_t)); ++ if (FWINV(info->saddr != (src & info->smsk), ++ EBT_ARP_SRC_IP)) ++ return EBT_NOMATCH; ++ } ++ ++ if (info->bitmask & EBT_ARP_DST_IP) { ++ memcpy(&dst, ((*skb).nh.raw)+sizeof(struct arphdr) + ++ (2*(((*skb).nh.arph)->ar_hln)) + ++ (((*skb).nh.arph)->ar_pln), sizeof(uint32_t)); ++ if (FWINV(info->daddr != (dst & info->dmsk), ++ EBT_ARP_DST_IP)) ++ return EBT_NOMATCH; ++ } ++ } ++ ++ if (info->bitmask & (EBT_ARP_SRC_MAC | EBT_ARP_DST_MAC)) ++ { ++ uint32_t arp_len = sizeof(struct arphdr) + ++ (2 * (((*skb).nh.arph)->ar_hln)) + ++ (2 * (((*skb).nh.arph)->ar_pln)); ++ unsigned char dst[ETH_ALEN]; ++ unsigned char src[ETH_ALEN]; ++ ++ // Make sure the packet is long enough. ++ if ((((*skb).nh.raw) + arp_len) > (*skb).tail) ++ return EBT_NOMATCH; ++ // MAC addresses are 6 bytes. ++ if (((*skb).nh.arph)->ar_hln != ETH_ALEN) ++ return EBT_NOMATCH; ++ if (info->bitmask & EBT_ARP_SRC_MAC) { ++ uint8_t verdict, i; ++ ++ memcpy(&src, ((*skb).nh.raw) + ++ sizeof(struct arphdr), ++ ETH_ALEN); ++ verdict = 0; ++ for (i = 0; i < 6; i++) ++ verdict |= (src[i] ^ info->smaddr[i]) & ++ info->smmsk[i]; ++ if (FWINV(verdict != 0, EBT_ARP_SRC_MAC)) ++ return EBT_NOMATCH; ++ } ++ ++ if (info->bitmask & EBT_ARP_DST_MAC) { ++ uint8_t verdict, i; ++ ++ memcpy(&dst, ((*skb).nh.raw) + ++ sizeof(struct arphdr) + ++ (((*skb).nh.arph)->ar_hln) + ++ (((*skb).nh.arph)->ar_pln), ++ ETH_ALEN); ++ verdict = 0; ++ for (i = 0; i < 6; i++) ++ verdict |= (dst[i] ^ info->dmaddr[i]) & ++ info->dmmsk[i]; ++ if (FWINV(verdict != 0, EBT_ARP_DST_MAC)) ++ return EBT_NOMATCH; ++ } ++ } ++ ++ return EBT_MATCH; ++} ++ ++static int ebt_arp_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_arp_info *info = (struct ebt_arp_info *)data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_arp_info))) ++ return -EINVAL; ++ if ((e->ethproto != __constant_htons(ETH_P_ARP) && ++ e->ethproto != __constant_htons(ETH_P_RARP)) || ++ e->invflags & EBT_IPROTO) ++ return -EINVAL; ++ if (info->bitmask & ~EBT_ARP_MASK || info->invflags & ~EBT_ARP_MASK) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_match filter_arp = ++{ ++ {NULL, NULL}, EBT_ARP_MATCH, ebt_filter_arp, ebt_arp_check, NULL, ++ THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_match(&filter_arp); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_match(&filter_arp); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_arpreply.c src/linux/linux/net/bridge/netfilter/ebt_arpreply.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_arpreply.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_arpreply.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,86 @@ ++/* ++ * ebt_arpreply ++ * ++ * Authors: ++ * Grzegorz Borowiak ++ * Bart De Schuymer ++ * ++ * August, 2003 ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static int ebt_target_reply(struct sk_buff **pskb, unsigned int hooknr, ++ const struct net_device *in, const struct net_device *out, ++ const void *data, unsigned int datalen) ++{ ++ struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data; ++ struct arphdr *ah; ++ unsigned char *sha, *arp_ptr; ++ u32 sip, tip; ++ ++ ah = (**pskb).nh.arph; ++ if (ah->ar_op != __constant_htons(ARPOP_REQUEST) || ++ ah->ar_hln != ETH_ALEN || ah->ar_pro != htons(ETH_P_IP) || ++ ah->ar_pln != 4) ++ return EBT_CONTINUE; ++ ++ arp_ptr = (unsigned char *)(ah + 1); ++ ++ /* get source and target IP */ ++ sha = arp_ptr; ++ arp_ptr += ETH_ALEN; ++ memcpy(&sip, arp_ptr, 4); ++ arp_ptr += 4 + ETH_ALEN; ++ memcpy(&tip, arp_ptr, 4); ++ ++ arp_send(ARPOP_REPLY, ETH_P_ARP, sip, in, tip, sha, info->mac, sha); ++ ++ return info->target; ++} ++ ++static int ebt_target_reply_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_arpreply_info *info = (struct ebt_arpreply_info *)data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_arpreply_info))) ++ return -EINVAL; ++ if (BASE_CHAIN && info->target == EBT_RETURN) ++ return -EINVAL; ++ if (e->ethproto != __constant_htons(ETH_P_ARP) || ++ e->invflags & EBT_IPROTO) ++ return -EINVAL; ++ CLEAR_BASE_CHAIN_BIT; ++ if (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_target reply_target = ++{ ++ .name = EBT_ARPREPLY_TARGET, ++ .target = ebt_target_reply, ++ .check = ebt_target_reply_check, ++ .me = THIS_MODULE, ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_target(&reply_target); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_target(&reply_target); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_dnat.c src/linux/linux/net/bridge/netfilter/ebt_dnat.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_dnat.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_dnat.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,65 @@ ++/* ++ * ebt_dnat ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * June, 2002 ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++ ++static int ebt_target_dnat(struct sk_buff **pskb, unsigned int hooknr, ++ const struct net_device *in, const struct net_device *out, ++ const void *data, unsigned int datalen) ++{ ++ struct ebt_nat_info *info = (struct ebt_nat_info *)data; ++ ++ memcpy(((**pskb).mac.ethernet)->h_dest, info->mac, ++ ETH_ALEN * sizeof(unsigned char)); ++ return info->target; ++} ++ ++static int ebt_target_dnat_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_nat_info *info = (struct ebt_nat_info *)data; ++ ++ if (BASE_CHAIN && info->target == EBT_RETURN) ++ return -EINVAL; ++ CLEAR_BASE_CHAIN_BIT; ++ if ( (strcmp(tablename, "nat") || ++ (hookmask & ~((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT)))) && ++ (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) ++ return -EINVAL; ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info))) ++ return -EINVAL; ++ if (INVALID_TARGET) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_target dnat = ++{ ++ {NULL, NULL}, EBT_DNAT_TARGET, ebt_target_dnat, ebt_target_dnat_check, ++ NULL, THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_target(&dnat); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_target(&dnat); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_ip.c src/linux/linux/net/bridge/netfilter/ebt_ip.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_ip.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_ip.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,121 @@ ++/* ++ * ebt_ip ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * April, 2002 ++ * ++ * Changes: ++ * added ip-sport and ip-dport ++ * Innominate Security Technologies AG ++ * September, 2002 ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++struct tcpudphdr { ++ uint16_t src; ++ uint16_t dst; ++}; ++ ++union h_u { ++ unsigned char *raw; ++ struct tcpudphdr *tuh; ++}; ++ ++static int ebt_filter_ip(const struct sk_buff *skb, const struct net_device *in, ++ const struct net_device *out, const void *data, ++ unsigned int datalen) ++{ ++ struct ebt_ip_info *info = (struct ebt_ip_info *)data; ++ ++ if (info->bitmask & EBT_IP_TOS && ++ FWINV(info->tos != ((*skb).nh.iph)->tos, EBT_IP_TOS)) ++ return EBT_NOMATCH; ++ if (info->bitmask & EBT_IP_PROTO) { ++ if (FWINV(info->protocol != ((*skb).nh.iph)->protocol, ++ EBT_IP_PROTO)) ++ return EBT_NOMATCH; ++ if ( info->protocol == IPPROTO_TCP || ++ info->protocol == IPPROTO_UDP ) ++ { ++ union h_u h; ++ h.raw = skb->data + skb->nh.iph->ihl*4; ++ if (info->bitmask & EBT_IP_DPORT) { ++ uint16_t port = ntohs(h.tuh->dst); ++ if (FWINV(port < info->dport[0] || ++ port > info->dport[1], ++ EBT_IP_DPORT)) ++ return EBT_NOMATCH; ++ } ++ if (info->bitmask & EBT_IP_SPORT) { ++ uint16_t port = ntohs(h.tuh->src); ++ if (FWINV(port < info->sport[0] || ++ port > info->sport[1], ++ EBT_IP_SPORT)) ++ return EBT_NOMATCH; ++ } ++ } ++ } ++ if (info->bitmask & EBT_IP_SOURCE && ++ FWINV((((*skb).nh.iph)->saddr & info->smsk) != ++ info->saddr, EBT_IP_SOURCE)) ++ return EBT_NOMATCH; ++ if ((info->bitmask & EBT_IP_DEST) && ++ FWINV((((*skb).nh.iph)->daddr & info->dmsk) != ++ info->daddr, EBT_IP_DEST)) ++ return EBT_NOMATCH; ++ return EBT_MATCH; ++} ++ ++static int ebt_ip_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_ip_info *info = (struct ebt_ip_info *)data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_ip_info))) ++ return -EINVAL; ++ if (e->ethproto != __constant_htons(ETH_P_IP) || ++ e->invflags & EBT_IPROTO) ++ return -EINVAL; ++ if (info->bitmask & ~EBT_IP_MASK || info->invflags & ~EBT_IP_MASK) ++ return -EINVAL; ++ if (info->bitmask & (EBT_IP_DPORT | EBT_IP_SPORT)) { ++ if (!info->bitmask & EBT_IPROTO) ++ return -EINVAL; ++ if (info->protocol != IPPROTO_TCP && ++ info->protocol != IPPROTO_UDP) ++ return -EINVAL; ++ } ++ if (info->bitmask & EBT_IP_DPORT && info->dport[0] > info->dport[1]) ++ return -EINVAL; ++ if (info->bitmask & EBT_IP_SPORT && info->sport[0] > info->sport[1]) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_match filter_ip = ++{ ++ {NULL, NULL}, EBT_IP_MATCH, ebt_filter_ip, ebt_ip_check, NULL, ++ THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_match(&filter_ip); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_match(&filter_ip); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_limit.c src/linux/linux/net/bridge/netfilter/ebt_limit.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_limit.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_limit.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,101 @@ ++/* ++ * ebt_limit ++ * ++ * Authors: ++ * Tom Marshall ++ * ++ * Mostly copied from netfilter's ipt_limit.c, see that file for explanation ++ * ++ * September, 2003 ++ * ++ */ ++ ++#include ++#include ++#include ++ ++#include ++#include ++ ++static spinlock_t limit_lock = SPIN_LOCK_UNLOCKED; ++ ++#define CREDITS_PER_JIFFY 128 ++ ++static int ebt_limit_match(const struct sk_buff *skb, const struct net_device *in, ++ const struct net_device *out, const void *data, unsigned int datalen) ++{ ++ struct ebt_limit_info *info = (struct ebt_limit_info *)data; ++ unsigned long now = jiffies; ++ ++ spin_lock_bh(&limit_lock); ++ info->credit += (now - xchg(&info->prev, now)) * CREDITS_PER_JIFFY; ++ if (info->credit > info->credit_cap) ++ info->credit = info->credit_cap; ++ ++ if (info->credit >= info->cost) { ++ /* We're not limited. */ ++ info->credit -= info->cost; ++ spin_unlock_bh(&limit_lock); ++ return EBT_MATCH; ++ } ++ ++ spin_unlock_bh(&limit_lock); ++ return EBT_NOMATCH; ++} ++ ++/* Precision saver. */ ++static u_int32_t ++user2credits(u_int32_t user) ++{ ++ /* If multiplying would overflow... */ ++ if (user > 0xFFFFFFFF / (HZ*CREDITS_PER_JIFFY)) ++ /* Divide first. */ ++ return (user / EBT_LIMIT_SCALE) * HZ * CREDITS_PER_JIFFY; ++ ++ return (user * HZ * CREDITS_PER_JIFFY) / EBT_LIMIT_SCALE; ++} ++ ++static int ebt_limit_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_limit_info *info = (struct ebt_limit_info *)data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_limit_info))) ++ return -EINVAL; ++ ++ /* Check for overflow. */ ++ if (info->burst == 0 ++ || user2credits(info->avg * info->burst) < user2credits(info->avg)) { ++ printk("Overflow in ebt_limit: %u/%u\n", ++ info->avg, info->burst); ++ return -EINVAL; ++ } ++ ++ /* User avg in seconds * EBT_LIMIT_SCALE: convert to jiffies * 128. */ ++ info->prev = jiffies; ++ info->credit = user2credits(info->avg * info->burst); ++ info->credit_cap = user2credits(info->avg * info->burst); ++ info->cost = user2credits(info->avg); ++ return 0; ++} ++ ++static struct ebt_match ebt_limit_reg = ++{ ++ {NULL, NULL}, EBT_LIMIT_MATCH, ebt_limit_match, ebt_limit_check, NULL, ++ THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_match(&ebt_limit_reg); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_match(&ebt_limit_reg); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_log.c src/linux/linux/net/bridge/netfilter/ebt_log.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_log.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_log.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,152 @@ ++/* ++ * ebt_log ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * April, 2002 ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++static spinlock_t ebt_log_lock = SPIN_LOCK_UNLOCKED; ++ ++static int ebt_log_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_log_info *info = (struct ebt_log_info *)data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_log_info))) ++ return -EINVAL; ++ if (info->bitmask & ~EBT_LOG_MASK) ++ return -EINVAL; ++ if (info->loglevel >= 8) ++ return -EINVAL; ++ info->prefix[EBT_LOG_PREFIX_SIZE - 1] = '\0'; ++ return 0; ++} ++ ++struct tcpudphdr ++{ ++ uint16_t src; ++ uint16_t dst; ++}; ++ ++struct arppayload ++{ ++ unsigned char mac_src[ETH_ALEN]; ++ unsigned char ip_src[4]; ++ unsigned char mac_dst[ETH_ALEN]; ++ unsigned char ip_dst[4]; ++}; ++ ++static void print_MAC(unsigned char *p) ++{ ++ int i; ++ ++ for (i = 0; i < ETH_ALEN; i++, p++) ++ printk("%02x%c", *p, i == ETH_ALEN - 1 ? ' ':':'); ++} ++ ++#define myNIPQUAD(a) a[0], a[1], a[2], a[3] ++static void ebt_log(const struct sk_buff *skb, const struct net_device *in, ++ const struct net_device *out, const void *data, unsigned int datalen) ++{ ++ struct ebt_log_info *info = (struct ebt_log_info *)data; ++ char level_string[4] = "< >"; ++ level_string[1] = '0' + info->loglevel; ++ ++ spin_lock_bh(&ebt_log_lock); ++ printk(level_string); ++ printk("%s IN=%s OUT=%s ", info->prefix, in ? in->name : "", ++ out ? out->name : ""); ++ ++ printk("MAC source = "); ++ print_MAC((skb->mac.ethernet)->h_source); ++ printk("MAC dest = "); ++ print_MAC((skb->mac.ethernet)->h_dest); ++ ++ printk("proto = 0x%04x", ntohs(((*skb).mac.ethernet)->h_proto)); ++ ++ if ((info->bitmask & EBT_LOG_IP) && skb->mac.ethernet->h_proto == ++ htons(ETH_P_IP)){ ++ struct iphdr *iph = skb->nh.iph; ++ printk(" IP SRC=%u.%u.%u.%u IP DST=%u.%u.%u.%u,", ++ NIPQUAD(iph->saddr), NIPQUAD(iph->daddr)); ++ printk(" IP tos=0x%02X, IP proto=%d", iph->tos, iph->protocol); ++ if (iph->protocol == IPPROTO_TCP || ++ iph->protocol == IPPROTO_UDP) { ++ struct tcpudphdr *ports = (struct tcpudphdr *)(skb->data + iph->ihl*4); ++ ++ if (skb->data + iph->ihl*4 > skb->tail) { ++ printk(" INCOMPLETE TCP/UDP header"); ++ goto out; ++ } ++ printk(" SPT=%u DPT=%u", ntohs(ports->src), ++ ntohs(ports->dst)); ++ } ++ goto out; ++ } ++ ++ if ((info->bitmask & EBT_LOG_ARP) && ++ ((skb->mac.ethernet->h_proto == __constant_htons(ETH_P_ARP)) || ++ (skb->mac.ethernet->h_proto == __constant_htons(ETH_P_RARP)))) { ++ struct arphdr * arph = skb->nh.arph; ++ printk(" ARP HTYPE=%d, PTYPE=0x%04x, OPCODE=%d", ++ ntohs(arph->ar_hrd), ntohs(arph->ar_pro), ++ ntohs(arph->ar_op)); ++ /* If it's for Ethernet and the lengths are OK, ++ * then log the ARP payload */ ++ if (arph->ar_hrd == __constant_htons(1) && ++ arph->ar_hln == ETH_ALEN && ++ arph->ar_pln == sizeof(uint32_t)) { ++ struct arppayload *arpp = (struct arppayload *)(skb->data + sizeof(*arph)); ++ ++ if (skb->data + sizeof(*arph) > skb->tail) { ++ printk(" INCOMPLETE ARP header"); ++ goto out; ++ } ++ ++ printk(" ARP MAC SRC="); ++ print_MAC(arpp->mac_src); ++ printk(" ARP IP SRC=%u.%u.%u.%u", ++ myNIPQUAD(arpp->ip_src)); ++ printk(" ARP MAC DST="); ++ print_MAC(arpp->mac_dst); ++ printk(" ARP IP DST=%u.%u.%u.%u", ++ myNIPQUAD(arpp->ip_dst)); ++ } ++ ++ } ++out: ++ printk("\n"); ++ spin_unlock_bh(&ebt_log_lock); ++} ++ ++static struct ebt_watcher log = ++{ ++ {NULL, NULL}, EBT_LOG_WATCHER, ebt_log, ebt_log_check, NULL, ++ THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_watcher(&log); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_watcher(&log); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_mark.c src/linux/linux/net/bridge/netfilter/ebt_mark.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_mark.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_mark.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,66 @@ ++/* ++ * ebt_mark ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * July, 2002 ++ * ++ */ ++ ++// The mark target can be used in any chain ++// I believe adding a mangle table just for marking is total overkill ++// Marking a frame doesn't really change anything in the frame anyway ++ ++#include ++#include ++#include ++ ++static int ebt_target_mark(struct sk_buff **pskb, unsigned int hooknr, ++ const struct net_device *in, const struct net_device *out, ++ const void *data, unsigned int datalen) ++{ ++ struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data; ++ ++ if ((*pskb)->nfmark != info->mark) { ++ (*pskb)->nfmark = info->mark; ++ (*pskb)->nfcache |= NFC_ALTERED; ++ } ++ return info->target; ++} ++ ++static int ebt_target_mark_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_mark_t_info *info = (struct ebt_mark_t_info *)data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_t_info))) ++ return -EINVAL; ++ if (BASE_CHAIN && info->target == EBT_RETURN) ++ return -EINVAL; ++ CLEAR_BASE_CHAIN_BIT; ++ if (INVALID_TARGET) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_target mark_target = ++{ ++ {NULL, NULL}, EBT_MARK_TARGET, ebt_target_mark, ++ ebt_target_mark_check, NULL, THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_target(&mark_target); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_target(&mark_target); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_mark_m.c src/linux/linux/net/bridge/netfilter/ebt_mark_m.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_mark_m.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_mark_m.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,61 @@ ++/* ++ * ebt_mark_m ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * July, 2002 ++ * ++ */ ++ ++#include ++#include ++#include ++ ++static int ebt_filter_mark(const struct sk_buff *skb, ++ const struct net_device *in, const struct net_device *out, const void *data, ++ unsigned int datalen) ++{ ++ struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data; ++ ++ if (info->bitmask & EBT_MARK_OR) ++ return !(!!(skb->nfmark & info->mask) ^ info->invert); ++ return !(((skb->nfmark & info->mask) == info->mark) ^ info->invert); ++} ++ ++static int ebt_mark_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_mark_m_info *info = (struct ebt_mark_m_info *) data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_mark_m_info))) ++ return -EINVAL; ++ if (info->bitmask & ~EBT_MARK_MASK) ++ return -EINVAL; ++ if ((info->bitmask & EBT_MARK_OR) && (info->bitmask & EBT_MARK_AND)) ++ return -EINVAL; ++ if (!info->bitmask) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_match filter_mark = ++{ ++ {NULL, NULL}, EBT_MARK_MATCH, ebt_filter_mark, ebt_mark_check, NULL, ++ THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_match(&filter_mark); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_match(&filter_mark); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_pkttype.c src/linux/linux/net/bridge/netfilter/ebt_pkttype.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_pkttype.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_pkttype.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,60 @@ ++/* ++ * ebt_pkttype ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * April, 2003 ++ * ++ */ ++ ++#include ++#include ++#include ++ ++static int ebt_filter_pkttype(const struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ const void *data, ++ unsigned int datalen) ++{ ++ struct ebt_pkttype_info *info = (struct ebt_pkttype_info *)data; ++ ++ return (skb->pkt_type != info->pkt_type) ^ info->invert; ++} ++ ++static int ebt_pkttype_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_pkttype_info *info = (struct ebt_pkttype_info *)data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_pkttype_info))) ++ return -EINVAL; ++ if (info->invert != 0 && info->invert != 1) ++ return -EINVAL; ++ /* Allow any pkt_type value */ ++ return 0; ++} ++ ++static struct ebt_match filter_pkttype = ++{ ++ .name = EBT_PKTTYPE_MATCH, ++ .match = ebt_filter_pkttype, ++ .check = ebt_pkttype_check, ++ .me = THIS_MODULE, ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_match(&filter_pkttype); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_match(&filter_pkttype); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_redirect.c src/linux/linux/net/bridge/netfilter/ebt_redirect.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_redirect.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_redirect.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,71 @@ ++/* ++ * ebt_redirect ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * April, 2002 ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include "../br_private.h" ++ ++static int ebt_target_redirect(struct sk_buff **pskb, unsigned int hooknr, ++ const struct net_device *in, const struct net_device *out, ++ const void *data, unsigned int datalen) ++{ ++ struct ebt_redirect_info *info = (struct ebt_redirect_info *)data; ++ ++ if (hooknr != NF_BR_BROUTING) ++ memcpy((**pskb).mac.ethernet->h_dest, ++ in->br_port->br->dev.dev_addr, ETH_ALEN); ++ else { ++ memcpy((**pskb).mac.ethernet->h_dest, ++ in->dev_addr, ETH_ALEN); ++ (*pskb)->pkt_type = PACKET_HOST; ++ } ++ return info->target; ++} ++ ++static int ebt_target_redirect_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_redirect_info *info = (struct ebt_redirect_info *)data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_redirect_info))) ++ return -EINVAL; ++ if (BASE_CHAIN && info->target == EBT_RETURN) ++ return -EINVAL; ++ CLEAR_BASE_CHAIN_BIT; ++ if ( (strcmp(tablename, "nat") || hookmask & ~(1 << NF_BR_PRE_ROUTING)) && ++ (strcmp(tablename, "broute") || hookmask & ~(1 << NF_BR_BROUTING)) ) ++ return -EINVAL; ++ if (INVALID_TARGET) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_target redirect_target = ++{ ++ {NULL, NULL}, EBT_REDIRECT_TARGET, ebt_target_redirect, ++ ebt_target_redirect_check, NULL, THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_target(&redirect_target); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_target(&redirect_target); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_snat.c src/linux/linux/net/bridge/netfilter/ebt_snat.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_snat.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_snat.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,64 @@ ++/* ++ * ebt_snat ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * June, 2002 ++ * ++ */ ++ ++#include ++#include ++#include ++ ++static int ebt_target_snat(struct sk_buff **pskb, unsigned int hooknr, ++ const struct net_device *in, const struct net_device *out, ++ const void *data, unsigned int datalen) ++{ ++ struct ebt_nat_info *info = (struct ebt_nat_info *) data; ++ ++ memcpy(((**pskb).mac.ethernet)->h_source, info->mac, ++ ETH_ALEN * sizeof(unsigned char)); ++ return info->target; ++} ++ ++static int ebt_target_snat_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_nat_info *info = (struct ebt_nat_info *) data; ++ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_nat_info))) ++ return -EINVAL; ++ if (BASE_CHAIN && info->target == EBT_RETURN) ++ return -EINVAL; ++ CLEAR_BASE_CHAIN_BIT; ++ if (strcmp(tablename, "nat")) ++ return -EINVAL; ++ if (hookmask & ~(1 << NF_BR_POST_ROUTING)) ++ return -EINVAL; ++ if (INVALID_TARGET) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_target snat = ++{ ++ {NULL, NULL}, EBT_SNAT_TARGET, ebt_target_snat, ebt_target_snat_check, ++ NULL, THIS_MODULE ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_target(&snat); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_target(&snat); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_stp.c src/linux/linux/net/bridge/netfilter/ebt_stp.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_stp.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_stp.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,191 @@ ++/* ++ * ebt_stp ++ * ++ * Authors: ++ * Bart De Schuymer ++ * Stephen Hemminger ++ * ++ * June, 2003 ++ */ ++ ++#include ++#include ++#include ++ ++#define BPDU_TYPE_CONFIG 0 ++#define BPDU_TYPE_TCN 0x80 ++ ++struct stp_header { ++ uint8_t dsap; ++ uint8_t ssap; ++ uint8_t ctrl; ++ uint8_t pid; ++ uint8_t vers; ++ uint8_t type; ++}; ++ ++struct stp_config_pdu { ++ uint8_t flags; ++ uint8_t root[8]; ++ uint8_t root_cost[4]; ++ uint8_t sender[8]; ++ uint8_t port[2]; ++ uint8_t msg_age[2]; ++ uint8_t max_age[2]; ++ uint8_t hello_time[2]; ++ uint8_t forward_delay[2]; ++}; ++ ++#define NR16(p) (p[0] << 8 | p[1]) ++#define NR32(p) ((p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]) ++ ++static int ebt_filter_config(struct ebt_stp_info *info, ++ struct stp_config_pdu *stpc) ++{ ++ struct ebt_stp_config_info *c; ++ uint16_t v16; ++ uint32_t v32; ++ int verdict, i; ++ ++ c = &info->config; ++ if ((info->bitmask & EBT_STP_FLAGS) && ++ FWINV(c->flags != stpc->flags, EBT_STP_FLAGS)) ++ return EBT_NOMATCH; ++ if (info->bitmask & EBT_STP_ROOTPRIO) { ++ v16 = NR16(stpc->root); ++ if (FWINV(v16 < c->root_priol || ++ v16 > c->root_priou, EBT_STP_ROOTPRIO)) ++ return EBT_NOMATCH; ++ } ++ if (info->bitmask & EBT_STP_ROOTADDR) { ++ verdict = 0; ++ for (i = 0; i < 6; i++) ++ verdict |= (stpc->root[2+i] ^ c->root_addr[i]) & ++ c->root_addrmsk[i]; ++ if (FWINV(verdict != 0, EBT_STP_ROOTADDR)) ++ return EBT_NOMATCH; ++ } ++ if (info->bitmask & EBT_STP_ROOTCOST) { ++ v32 = NR32(stpc->root_cost); ++ if (FWINV(v32 < c->root_costl || ++ v32 > c->root_costu, EBT_STP_ROOTCOST)) ++ return EBT_NOMATCH; ++ } ++ if (info->bitmask & EBT_STP_SENDERPRIO) { ++ v16 = NR16(stpc->sender); ++ if (FWINV(v16 < c->sender_priol || ++ v16 > c->sender_priou, EBT_STP_SENDERPRIO)) ++ return EBT_NOMATCH; ++ } ++ if (info->bitmask & EBT_STP_SENDERADDR) { ++ verdict = 0; ++ for (i = 0; i < 6; i++) ++ verdict |= (stpc->sender[2+i] ^ c->sender_addr[i]) & ++ c->sender_addrmsk[i]; ++ if (FWINV(verdict != 0, EBT_STP_SENDERADDR)) ++ return EBT_NOMATCH; ++ } ++ if (info->bitmask & EBT_STP_PORT) { ++ v16 = NR16(stpc->port); ++ if (FWINV(v16 < c->portl || ++ v16 > c->portu, EBT_STP_PORT)) ++ return EBT_NOMATCH; ++ } ++ if (info->bitmask & EBT_STP_MSGAGE) { ++ v16 = NR16(stpc->msg_age); ++ if (FWINV(v16 < c->msg_agel || ++ v16 > c->msg_ageu, EBT_STP_MSGAGE)) ++ return EBT_NOMATCH; ++ } ++ if (info->bitmask & EBT_STP_MAXAGE) { ++ v16 = NR16(stpc->max_age); ++ if (FWINV(v16 < c->max_agel || ++ v16 > c->max_ageu, EBT_STP_MAXAGE)) ++ return EBT_NOMATCH; ++ } ++ if (info->bitmask & EBT_STP_HELLOTIME) { ++ v16 = NR16(stpc->hello_time); ++ if (FWINV(v16 < c->hello_timel || ++ v16 > c->hello_timeu, EBT_STP_HELLOTIME)) ++ return EBT_NOMATCH; ++ } ++ if (info->bitmask & EBT_STP_FWDD) { ++ v16 = NR16(stpc->forward_delay); ++ if (FWINV(v16 < c->forward_delayl || ++ v16 > c->forward_delayu, EBT_STP_FWDD)) ++ return EBT_NOMATCH; ++ } ++ return EBT_MATCH; ++} ++ ++static int ebt_filter_stp(const struct sk_buff *skb, const struct net_device *in, ++ const struct net_device *out, const void *data, unsigned int datalen) ++{ ++ struct ebt_stp_info *info = (struct ebt_stp_info *)data; ++ struct stp_header stph; ++ uint8_t header[6] = {0x42, 0x42, 0x03, 0x00, 0x00, 0x00}; ++ if (skb_copy_bits(skb, 0, &stph, sizeof(stph))) ++ return EBT_NOMATCH; ++ ++ /* The stp code only considers these */ ++ if (memcmp(&stph, header, sizeof(header))) ++ return EBT_NOMATCH; ++ ++ if (info->bitmask & EBT_STP_TYPE ++ && FWINV(info->type != stph.type, EBT_STP_TYPE)) ++ return EBT_NOMATCH; ++ ++ if (stph.type == BPDU_TYPE_CONFIG && ++ info->bitmask & EBT_STP_CONFIG_MASK) { ++ struct stp_config_pdu stpc; ++ ++ if (skb_copy_bits(skb, sizeof(stph), &stpc, sizeof(stpc))) ++ return EBT_NOMATCH; ++ return ebt_filter_config(info, &stpc); ++ } ++ return EBT_MATCH; ++} ++ ++static int ebt_stp_check(const char *tablename, unsigned int hookmask, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_stp_info *info = (struct ebt_stp_info *)data; ++ int len = EBT_ALIGN(sizeof(struct ebt_stp_info)); ++ uint8_t bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }; ++ uint8_t msk[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; ++ ++ if (info->bitmask & ~EBT_STP_MASK || info->invflags & ~EBT_STP_MASK || ++ !(info->bitmask & EBT_STP_MASK)) ++ return -EINVAL; ++ if (datalen != len) ++ return -EINVAL; ++ /* Make sure the match only receives stp frames */ ++ if (memcmp(e->destmac, bridge_ula, ETH_ALEN) || ++ memcmp(e->destmsk, msk, ETH_ALEN) || !(e->bitmask & EBT_DESTMAC)) ++ return -EINVAL; ++ ++ return 0; ++} ++ ++static struct ebt_match filter_stp = ++{ ++ .name = EBT_STP_MATCH, ++ .match = ebt_filter_stp, ++ .check = ebt_stp_check, ++ .me = THIS_MODULE, ++}; ++ ++static int __init init(void) ++{ ++ return ebt_register_match(&filter_stp); ++} ++ ++static void __exit fini(void) ++{ ++ ebt_unregister_match(&filter_stp); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebt_vlan.c src/linux/linux/net/bridge/netfilter/ebt_vlan.c +--- src/linux/linux.stock/net/bridge/netfilter/ebt_vlan.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebt_vlan.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,259 @@ ++/* ++ * Description: EBTables 802.1Q match extension kernelspace module. ++ * Authors: Nick Fedchik ++ * Bart De Schuymer ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++static unsigned char debug; ++#define MODULE_VERSION "0.6" ++ ++MODULE_PARM(debug, "0-1b"); ++MODULE_PARM_DESC(debug, "debug=1 is turn on debug messages"); ++MODULE_AUTHOR("Nick Fedchik "); ++MODULE_DESCRIPTION("802.1Q match module (ebtables extension), v" ++ MODULE_VERSION); ++MODULE_LICENSE("GPL"); ++ ++ ++#define DEBUG_MSG(args...) if (debug) printk (KERN_DEBUG "ebt_vlan: " args) ++#define INV_FLAG(_inv_flag_) (info->invflags & _inv_flag_) ? "!" : "" ++#define GET_BITMASK(_BIT_MASK_) info->bitmask & _BIT_MASK_ ++#define SET_BITMASK(_BIT_MASK_) info->bitmask |= _BIT_MASK_ ++#define EXIT_ON_MISMATCH(_MATCH_,_MASK_) if (!((info->_MATCH_ == _MATCH_)^!!(info->invflags & _MASK_))) return 1; ++ ++/* ++ * Function description: ebt_filter_vlan() is main engine for ++ * checking passed 802.1Q frame according to ++ * the passed extension parameters (in the *data buffer) ++ * ebt_filter_vlan() is called after successfull check the rule params ++ * by ebt_check_vlan() function. ++ * Parameters: ++ * const struct sk_buff *skb - pointer to passed ethernet frame buffer ++ * const void *data - pointer to passed extension parameters ++ * unsigned int datalen - length of passed *data buffer ++ * const struct net_device *in - ++ * const struct net_device *out - ++ * const struct ebt_counter *c - ++ * Returned values: ++ * 0 - ok (all rule params matched) ++ * 1 - miss (rule params not acceptable to the parsed frame) ++ */ ++static int ++ebt_filter_vlan(const struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ const void *data, unsigned int datalen) ++{ ++ struct ebt_vlan_info *info = (struct ebt_vlan_info *) data; /* userspace data */ ++ struct vlan_ethhdr *frame = (struct vlan_ethhdr *) skb->mac.raw; /* Passed tagged frame */ ++ ++ unsigned short TCI; /* Whole TCI, given from parsed frame */ ++ unsigned short id; /* VLAN ID, given from frame TCI */ ++ unsigned char prio; /* user_priority, given from frame TCI */ ++ unsigned short encap; /* VLAN encapsulated Type/Length field, given from orig frame */ ++ ++ /* ++ * Tag Control Information (TCI) consists of the following elements: ++ * - User_priority. The user_priority field is three bits in length, ++ * interpreted as a binary number. ++ * - Canonical Format Indicator (CFI). The Canonical Format Indicator ++ * (CFI) is a single bit flag value. Currently ignored. ++ * - VLAN Identifier (VID). The VID is encoded as ++ * an unsigned binary number. ++ */ ++ TCI = ntohs(frame->h_vlan_TCI); ++ id = TCI & VLAN_VID_MASK; ++ prio = (TCI >> 13) & 0x7; ++ encap = frame->h_vlan_encapsulated_proto; ++ ++ /* ++ * Checking VLAN Identifier (VID) ++ */ ++ if (GET_BITMASK(EBT_VLAN_ID)) { /* Is VLAN ID parsed? */ ++ EXIT_ON_MISMATCH(id, EBT_VLAN_ID); ++ } ++ /* ++ * Checking user_priority ++ */ ++ if (GET_BITMASK(EBT_VLAN_PRIO)) { /* Is VLAN user_priority parsed? */ ++ EXIT_ON_MISMATCH(prio, EBT_VLAN_PRIO); ++ } ++ /* ++ * Checking Encapsulated Proto (Length/Type) field ++ */ ++ if (GET_BITMASK(EBT_VLAN_ENCAP)) { /* Is VLAN Encap parsed? */ ++ EXIT_ON_MISMATCH(encap, EBT_VLAN_ENCAP); ++ } ++ /* ++ * All possible extension parameters was parsed. ++ * If rule never returned by missmatch, then all ok. ++ */ ++ return 0; ++} ++ ++/* ++ * Function description: ebt_vlan_check() is called when userspace ++ * delivers the table entry to the kernel, ++ * and to check that userspace doesn't give a bad table. ++ * Parameters: ++ * const char *tablename - table name string ++ * unsigned int hooknr - hook number ++ * const struct ebt_entry *e - ebtables entry basic set ++ * const void *data - pointer to passed extension parameters ++ * unsigned int datalen - length of passed *data buffer ++ * Returned values: ++ * 0 - ok (all delivered rule params are correct) ++ * 1 - miss (rule params is out of range, invalid, incompatible, etc.) ++ */ ++static int ++ebt_check_vlan(const char *tablename, ++ unsigned int hooknr, ++ const struct ebt_entry *e, void *data, unsigned int datalen) ++{ ++ struct ebt_vlan_info *info = (struct ebt_vlan_info *) data; ++ ++ /* ++ * Parameters buffer overflow check ++ */ ++ if (datalen != EBT_ALIGN(sizeof(struct ebt_vlan_info))) { ++ DEBUG_MSG ++ ("passed size %d is not eq to ebt_vlan_info (%d)\n", ++ datalen, sizeof(struct ebt_vlan_info)); ++ return -EINVAL; ++ } ++ ++ /* ++ * Is it 802.1Q frame checked? ++ */ ++ if (e->ethproto != __constant_htons(ETH_P_8021Q)) { ++ DEBUG_MSG ++ ("passed entry proto %2.4X is not 802.1Q (8100)\n", ++ (unsigned short) ntohs(e->ethproto)); ++ return -EINVAL; ++ } ++ ++ /* ++ * Check for bitmask range ++ * True if even one bit is out of mask ++ */ ++ if (info->bitmask & ~EBT_VLAN_MASK) { ++ DEBUG_MSG("bitmask %2X is out of mask (%2X)\n", ++ info->bitmask, EBT_VLAN_MASK); ++ return -EINVAL; ++ } ++ ++ /* ++ * Check for inversion flags range ++ */ ++ if (info->invflags & ~EBT_VLAN_MASK) { ++ DEBUG_MSG("inversion flags %2X is out of mask (%2X)\n", ++ info->invflags, EBT_VLAN_MASK); ++ return -EINVAL; ++ } ++ ++ /* ++ * Reserved VLAN ID (VID) values ++ * ----------------------------- ++ * 0 - The null VLAN ID. ++ * 1 - The default Port VID (PVID) ++ * 0x0FFF - Reserved for implementation use. ++ * if_vlan.h: VLAN_GROUP_ARRAY_LEN 4096. ++ */ ++ if (GET_BITMASK(EBT_VLAN_ID)) { /* when vlan-id param was spec-ed */ ++ if (!!info->id) { /* if id!=0 => check vid range */ ++ if (info->id > VLAN_GROUP_ARRAY_LEN) { ++ DEBUG_MSG ++ ("id %d is out of range (1-4096)\n", ++ info->id); ++ return -EINVAL; ++ } ++ /* ++ * Note: This is valid VLAN-tagged frame point. ++ * Any value of user_priority are acceptable, ++ * but should be ignored according to 802.1Q Std. ++ * So we just drop the prio flag. ++ */ ++ info->bitmask &= ~EBT_VLAN_PRIO; ++ } ++ /* ++ * Else, id=0 (null VLAN ID) => user_priority range (any?) ++ */ ++ } ++ ++ if (GET_BITMASK(EBT_VLAN_PRIO)) { ++ if ((unsigned char) info->prio > 7) { ++ DEBUG_MSG ++ ("prio %d is out of range (0-7)\n", ++ info->prio); ++ return -EINVAL; ++ } ++ } ++ /* ++ * Check for encapsulated proto range - it is possible to be ++ * any value for u_short range. ++ * if_ether.h: ETH_ZLEN 60 - Min. octets in frame sans FCS ++ */ ++ if (GET_BITMASK(EBT_VLAN_ENCAP)) { ++ if ((unsigned short) ntohs(info->encap) < ETH_ZLEN) { ++ DEBUG_MSG ++ ("encap frame length %d is less than minimal\n", ++ ntohs(info->encap)); ++ return -EINVAL; ++ } ++ } ++ ++ return 0; ++} ++ ++static struct ebt_match filter_vlan = { ++ {NULL, NULL}, ++ EBT_VLAN_MATCH, ++ ebt_filter_vlan, ++ ebt_check_vlan, ++ NULL, ++ THIS_MODULE ++}; ++ ++/* ++ * Module initialization function. ++ */ ++static int __init init(void) ++{ ++ DEBUG_MSG("ebtables 802.1Q extension module v" ++ MODULE_VERSION "\n"); ++ DEBUG_MSG("module debug=%d\n", !!debug); ++ return ebt_register_match(&filter_vlan); ++} ++ ++/* ++ * Module "finalization" function ++ */ ++static void __exit fini(void) ++{ ++ ebt_unregister_match(&filter_vlan); ++} ++ ++module_init(init); ++module_exit(fini); ++ ++EXPORT_NO_SYMBOLS; +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebtable_broute.c src/linux/linux/net/bridge/netfilter/ebtable_broute.c +--- src/linux/linux.stock/net/bridge/netfilter/ebtable_broute.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebtable_broute.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,79 @@ ++/* ++ * ebtable_broute ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * April, 2002 ++ * ++ * This table lets you choose between routing and bridging for frames ++ * entering on a bridge enslaved nic. This table is traversed before any ++ * other ebtables table. See net/bridge/br_input.c. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++// EBT_ACCEPT means the frame will be bridged ++// EBT_DROP means the frame will be routed ++static struct ebt_entries initial_chain = ++ {0, "BROUTING", 0, EBT_ACCEPT, 0}; ++ ++static struct ebt_replace initial_table = ++{ ++ "broute", 1 << NF_BR_BROUTING, 0, sizeof(struct ebt_entries), ++ { [NF_BR_BROUTING]&initial_chain}, 0, NULL, (char *)&initial_chain ++}; ++ ++static int check(const struct ebt_table_info *info, unsigned int valid_hooks) ++{ ++ if (valid_hooks & ~(1 << NF_BR_BROUTING)) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_table broute_table = ++{ ++ {NULL, NULL}, "broute", &initial_table, 1 << NF_BR_BROUTING, ++ RW_LOCK_UNLOCKED, check, NULL ++}; ++ ++static int ebt_broute(struct sk_buff **pskb) ++{ ++ int ret; ++ ++ ret = ebt_do_table(NF_BR_BROUTING, pskb, (*pskb)->dev, NULL, ++ &broute_table); ++ if (ret == NF_DROP) ++ return 1; // route it ++ return 0; // bridge it ++} ++ ++static int __init init(void) ++{ ++ int ret; ++ ++ ret = ebt_register_table(&broute_table); ++ if (ret < 0) ++ return ret; ++ br_write_lock_bh(BR_NETPROTO_LOCK); ++ // see br_input.c ++ br_should_route_hook = ebt_broute; ++ br_write_unlock_bh(BR_NETPROTO_LOCK); ++ return ret; ++} ++ ++static void __exit fini(void) ++{ ++ br_write_lock_bh(BR_NETPROTO_LOCK); ++ br_should_route_hook = NULL; ++ br_write_unlock_bh(BR_NETPROTO_LOCK); ++ ebt_unregister_table(&broute_table); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebtable_filter.c src/linux/linux/net/bridge/netfilter/ebtable_filter.c +--- src/linux/linux.stock/net/bridge/netfilter/ebtable_filter.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebtable_filter.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,90 @@ ++/* ++ * ebtable_filter ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * April, 2002 ++ * ++ */ ++ ++#include ++#include ++ ++#define FILTER_VALID_HOOKS ((1 << NF_BR_LOCAL_IN) | (1 << NF_BR_FORWARD) | \ ++ (1 << NF_BR_LOCAL_OUT)) ++ ++static struct ebt_entries initial_chains[] = ++{ ++ {0, "INPUT", 0, EBT_ACCEPT, 0}, ++ {0, "FORWARD", 0, EBT_ACCEPT, 0}, ++ {0, "OUTPUT", 0, EBT_ACCEPT, 0} ++}; ++ ++static struct ebt_replace initial_table = ++{ ++ "filter", FILTER_VALID_HOOKS, 0, 3 * sizeof(struct ebt_entries), ++ { [NF_BR_LOCAL_IN]&initial_chains[0], [NF_BR_FORWARD]&initial_chains[1], ++ [NF_BR_LOCAL_OUT]&initial_chains[2] }, 0, NULL, (char *)initial_chains ++}; ++ ++static int check(const struct ebt_table_info *info, unsigned int valid_hooks) ++{ ++ if (valid_hooks & ~FILTER_VALID_HOOKS) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_table frame_filter = ++{ ++ {NULL, NULL}, "filter", &initial_table, FILTER_VALID_HOOKS, ++ RW_LOCK_UNLOCKED, check, NULL ++}; ++ ++static unsigned int ++ebt_hook (unsigned int hook, struct sk_buff **pskb, const struct net_device *in, ++ const struct net_device *out, int (*okfn)(struct sk_buff *)) ++{ ++ return ebt_do_table(hook, pskb, in, out, &frame_filter); ++} ++ ++static struct nf_hook_ops ebt_ops_filter[] = { ++ { { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_LOCAL_IN, ++ NF_BR_PRI_FILTER_BRIDGED}, ++ { { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_FORWARD, ++ NF_BR_PRI_FILTER_BRIDGED}, ++ { { NULL, NULL }, ebt_hook, PF_BRIDGE, NF_BR_LOCAL_OUT, ++ NF_BR_PRI_FILTER_OTHER} ++}; ++ ++static int __init init(void) ++{ ++ int i, j, ret; ++ ++ ret = ebt_register_table(&frame_filter); ++ if (ret < 0) ++ return ret; ++ for (i = 0; i < sizeof(ebt_ops_filter) / sizeof(ebt_ops_filter[0]); i++) ++ if ((ret = nf_register_hook(&ebt_ops_filter[i])) < 0) ++ goto cleanup; ++ return ret; ++cleanup: ++ for (j = 0; j < i; j++) ++ nf_unregister_hook(&ebt_ops_filter[j]); ++ ebt_unregister_table(&frame_filter); ++ return ret; ++} ++ ++static void __exit fini(void) ++{ ++ int i; ++ ++ for (i = 0; i < sizeof(ebt_ops_filter) / sizeof(ebt_ops_filter[0]); i++) ++ nf_unregister_hook(&ebt_ops_filter[i]); ++ ebt_unregister_table(&frame_filter); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebtable_nat.c src/linux/linux/net/bridge/netfilter/ebtable_nat.c +--- src/linux/linux.stock/net/bridge/netfilter/ebtable_nat.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebtable_nat.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,96 @@ ++/* ++ * ebtable_nat ++ * ++ * Authors: ++ * Bart De Schuymer ++ * ++ * April, 2002 ++ * ++ */ ++ ++#include ++#include ++#define NAT_VALID_HOOKS ((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT) | \ ++ (1 << NF_BR_POST_ROUTING)) ++ ++static struct ebt_entries initial_chains[] = ++{ ++ {0, "PREROUTING", 0, EBT_ACCEPT, 0}, ++ {0, "OUTPUT", 0, EBT_ACCEPT, 0}, ++ {0, "POSTROUTING", 0, EBT_ACCEPT, 0} ++}; ++ ++static struct ebt_replace initial_table = ++{ ++ "nat", NAT_VALID_HOOKS, 0, 3 * sizeof(struct ebt_entries), ++ { [NF_BR_PRE_ROUTING]&initial_chains[0], [NF_BR_LOCAL_OUT]&initial_chains[1], ++ [NF_BR_POST_ROUTING]&initial_chains[2] }, 0, NULL, (char *)initial_chains ++}; ++ ++static int check(const struct ebt_table_info *info, unsigned int valid_hooks) ++{ ++ if (valid_hooks & ~NAT_VALID_HOOKS) ++ return -EINVAL; ++ return 0; ++} ++ ++static struct ebt_table frame_nat = ++{ ++ {NULL, NULL}, "nat", &initial_table, NAT_VALID_HOOKS, ++ RW_LOCK_UNLOCKED, check, NULL ++}; ++ ++static unsigned int ++ebt_nat_dst(unsigned int hook, struct sk_buff **pskb, const struct net_device *in ++ , const struct net_device *out, int (*okfn)(struct sk_buff *)) ++{ ++ return ebt_do_table(hook, pskb, in, out, &frame_nat); ++} ++ ++static unsigned int ++ebt_nat_src(unsigned int hook, struct sk_buff **pskb, const struct net_device *in ++ , const struct net_device *out, int (*okfn)(struct sk_buff *)) ++{ ++ return ebt_do_table(hook, pskb, in, out, &frame_nat); ++} ++ ++static struct nf_hook_ops ebt_ops_nat[] = { ++ { { NULL, NULL }, ebt_nat_dst, PF_BRIDGE, NF_BR_LOCAL_OUT, ++ NF_BR_PRI_NAT_DST_OTHER}, ++ { { NULL, NULL }, ebt_nat_src, PF_BRIDGE, NF_BR_POST_ROUTING, ++ NF_BR_PRI_NAT_SRC}, ++ { { NULL, NULL }, ebt_nat_dst, PF_BRIDGE, NF_BR_PRE_ROUTING, ++ NF_BR_PRI_NAT_DST_BRIDGED}, ++}; ++ ++static int __init init(void) ++{ ++ int i, ret, j; ++ ++ ret = ebt_register_table(&frame_nat); ++ if (ret < 0) ++ return ret; ++ for (i = 0; i < sizeof(ebt_ops_nat) / sizeof(ebt_ops_nat[0]); i++) ++ if ((ret = nf_register_hook(&ebt_ops_nat[i])) < 0) ++ goto cleanup; ++ return ret; ++cleanup: ++ for (j = 0; j < i; j++) ++ nf_unregister_hook(&ebt_ops_nat[j]); ++ ebt_unregister_table(&frame_nat); ++ return ret; ++} ++ ++static void __exit fini(void) ++{ ++ int i; ++ ++ for (i = 0; i < sizeof(ebt_ops_nat) / sizeof(ebt_ops_nat[0]); i++) ++ nf_unregister_hook(&ebt_ops_nat[i]); ++ ebt_unregister_table(&frame_nat); ++} ++ ++module_init(init); ++module_exit(fini); ++EXPORT_NO_SYMBOLS; ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/bridge/netfilter/ebtables.c src/linux/linux/net/bridge/netfilter/ebtables.c +--- src/linux/linux.stock/net/bridge/netfilter/ebtables.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/bridge/netfilter/ebtables.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,1490 @@ ++/* ++ * ebtables ++ * ++ * Author: ++ * Bart De Schuymer ++ * ++ * ebtables.c,v 2.0, July, 2002 ++ * ++ * This code is stongly inspired on the iptables code which is ++ * Copyright (C) 1999 Paul `Rusty' Russell & Michael J. Neuling ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License ++ * as published by the Free Software Foundation; either version ++ * 2 of the License, or (at your option) any later version. ++ */ ++ ++// used for print_string ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++// needed for logical [in,out]-dev filtering ++#include "../br_private.h" ++ ++// list_named_find ++#define ASSERT_READ_LOCK(x) ++#define ASSERT_WRITE_LOCK(x) ++#include ++ ++#if 0 // use this for remote debugging ++// Copyright (C) 1998 by Ori Pomerantz ++// Print the string to the appropriate tty, the one ++// the current task uses ++static void print_string(char *str) ++{ ++ struct tty_struct *my_tty; ++ ++ /* The tty for the current task */ ++ my_tty = current->tty; ++ if (my_tty != NULL) { ++ (*(my_tty->driver).write)(my_tty, 0, str, strlen(str)); ++ (*(my_tty->driver).write)(my_tty, 0, "\015\012", 2); ++ } ++} ++ ++#define BUGPRINT(args) print_string(args); ++#else ++#define BUGPRINT(format, args...) printk("kernel msg: ebtables bug: please "\ ++ "report to author: "format, ## args) ++// #define BUGPRINT(format, args...) ++#endif ++#define MEMPRINT(format, args...) printk("kernel msg: ebtables "\ ++ ": out of memory: "format, ## args) ++// #define MEMPRINT(format, args...) ++ ++ ++ ++// Each cpu has its own set of counters, so there is no need for write_lock in ++// the softirq ++// For reading or updating the counters, the user context needs to ++// get a write_lock ++ ++// The size of each set of counters is altered to get cache alignment ++#define SMP_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) ++#define COUNTER_OFFSET(n) (SMP_ALIGN(n * sizeof(struct ebt_counter))) ++#define COUNTER_BASE(c, n, cpu) ((struct ebt_counter *)(((char *)c) + \ ++ COUNTER_OFFSET(n) * cpu)) ++ ++ ++ ++static DECLARE_MUTEX(ebt_mutex); ++static LIST_HEAD(ebt_tables); ++static LIST_HEAD(ebt_targets); ++static LIST_HEAD(ebt_matches); ++static LIST_HEAD(ebt_watchers); ++ ++static struct ebt_target ebt_standard_target = ++{ {NULL, NULL}, EBT_STANDARD_TARGET, NULL, NULL, NULL, NULL}; ++ ++static inline int ebt_do_watcher (struct ebt_entry_watcher *w, ++ const struct sk_buff *skb, const struct net_device *in, ++ const struct net_device *out) ++{ ++ w->u.watcher->watcher(skb, in, out, w->data, ++ w->watcher_size); ++ // watchers don't give a verdict ++ return 0; ++} ++ ++static inline int ebt_do_match (struct ebt_entry_match *m, ++ const struct sk_buff *skb, const struct net_device *in, ++ const struct net_device *out) ++{ ++ return m->u.match->match(skb, in, out, m->data, ++ m->match_size); ++} ++ ++static inline int ebt_dev_check(char *entry, const struct net_device *device) ++{ ++ if (*entry == '\0') ++ return 0; ++ if (!device) ++ return 1; ++ return !!strcmp(entry, device->name); ++} ++ ++#define FWINV2(bool,invflg) ((bool) ^ !!(e->invflags & invflg)) ++// process standard matches ++static inline int ebt_basic_match(struct ebt_entry *e, struct ethhdr *h, ++ const struct net_device *in, const struct net_device *out) ++{ ++ int verdict, i; ++ ++ if (e->bitmask & EBT_802_3) { ++ if (FWINV2(ntohs(h->h_proto) >= 1536, EBT_IPROTO)) ++ return 1; ++ } else if (!(e->bitmask & EBT_NOPROTO) && ++ FWINV2(e->ethproto != h->h_proto, EBT_IPROTO)) ++ return 1; ++ ++ if (FWINV2(ebt_dev_check(e->in, in), EBT_IIN)) ++ return 1; ++ if (FWINV2(ebt_dev_check(e->out, out), EBT_IOUT)) ++ return 1; ++ if ((!in || !in->br_port) ? 0 : FWINV2(ebt_dev_check( ++ e->logical_in, &in->br_port->br->dev), EBT_ILOGICALIN)) ++ return 1; ++ if ((!out || !out->br_port) ? 0 : FWINV2(ebt_dev_check( ++ e->logical_out, &out->br_port->br->dev), EBT_ILOGICALOUT)) ++ return 1; ++ ++ if (e->bitmask & EBT_SOURCEMAC) { ++ verdict = 0; ++ for (i = 0; i < 6; i++) ++ verdict |= (h->h_source[i] ^ e->sourcemac[i]) & ++ e->sourcemsk[i]; ++ if (FWINV2(verdict != 0, EBT_ISOURCE) ) ++ return 1; ++ } ++ if (e->bitmask & EBT_DESTMAC) { ++ verdict = 0; ++ for (i = 0; i < 6; i++) ++ verdict |= (h->h_dest[i] ^ e->destmac[i]) & ++ e->destmsk[i]; ++ if (FWINV2(verdict != 0, EBT_IDEST) ) ++ return 1; ++ } ++ return 0; ++} ++ ++// Do some firewalling ++unsigned int ebt_do_table (unsigned int hook, struct sk_buff **pskb, ++ const struct net_device *in, const struct net_device *out, ++ struct ebt_table *table) ++{ ++ int i, nentries; ++ struct ebt_entry *point; ++ struct ebt_counter *counter_base, *cb_base; ++ struct ebt_entry_target *t; ++ int verdict, sp = 0; ++ struct ebt_chainstack *cs; ++ struct ebt_entries *chaininfo; ++ char *base; ++ struct ebt_table_info *private = table->private; ++ ++ read_lock_bh(&table->lock); ++ cb_base = COUNTER_BASE(private->counters, private->nentries, ++ cpu_number_map(smp_processor_id())); ++ if (private->chainstack) ++ cs = private->chainstack[cpu_number_map(smp_processor_id())]; ++ else ++ cs = NULL; ++ chaininfo = private->hook_entry[hook]; ++ nentries = private->hook_entry[hook]->nentries; ++ point = (struct ebt_entry *)(private->hook_entry[hook]->data); ++ counter_base = cb_base + private->hook_entry[hook]->counter_offset; ++ // base for chain jumps ++ base = private->entries; ++ i = 0; ++ while (i < nentries) { ++ if (ebt_basic_match(point, (**pskb).mac.ethernet, in, out)) ++ goto letscontinue; ++ ++ if (EBT_MATCH_ITERATE(point, ebt_do_match, *pskb, in, out) != 0) ++ goto letscontinue; ++ ++ // increase counter ++ (*(counter_base + i)).pcnt++; ++ (*(counter_base + i)).bcnt+=(**pskb).len; ++ ++ // these should only watch: not modify, nor tell us ++ // what to do with the packet ++ EBT_WATCHER_ITERATE(point, ebt_do_watcher, *pskb, in, ++ out); ++ ++ t = (struct ebt_entry_target *) ++ (((char *)point) + point->target_offset); ++ // standard target ++ if (!t->u.target->target) ++ verdict = ((struct ebt_standard_target *)t)->verdict; ++ else ++ verdict = t->u.target->target(pskb, hook, ++ in, out, t->data, t->target_size); ++ if (verdict == EBT_ACCEPT) { ++ read_unlock_bh(&table->lock); ++ return NF_ACCEPT; ++ } ++ if (verdict == EBT_DROP) { ++ read_unlock_bh(&table->lock); ++ return NF_DROP; ++ } ++ if (verdict == EBT_RETURN) { ++letsreturn: ++#ifdef CONFIG_NETFILTER_DEBUG ++ if (sp == 0) { ++ BUGPRINT("RETURN on base chain"); ++ // act like this is EBT_CONTINUE ++ goto letscontinue; ++ } ++#endif ++ sp--; ++ // put all the local variables right ++ i = cs[sp].n; ++ chaininfo = cs[sp].chaininfo; ++ nentries = chaininfo->nentries; ++ point = cs[sp].e; ++ counter_base = cb_base + ++ chaininfo->counter_offset; ++ continue; ++ } ++ if (verdict == EBT_CONTINUE) ++ goto letscontinue; ++#ifdef CONFIG_NETFILTER_DEBUG ++ if (verdict < 0) { ++ BUGPRINT("bogus standard verdict\n"); ++ read_unlock_bh(&table->lock); ++ return NF_DROP; ++ } ++#endif ++ // jump to a udc ++ cs[sp].n = i + 1; ++ cs[sp].chaininfo = chaininfo; ++ cs[sp].e = (struct ebt_entry *) ++ (((char *)point) + point->next_offset); ++ i = 0; ++ chaininfo = (struct ebt_entries *) (base + verdict); ++#ifdef CONFIG_NETFILTER_DEBUG ++ if (chaininfo->distinguisher) { ++ BUGPRINT("jump to non-chain\n"); ++ read_unlock_bh(&table->lock); ++ return NF_DROP; ++ } ++#endif ++ nentries = chaininfo->nentries; ++ point = (struct ebt_entry *)chaininfo->data; ++ counter_base = cb_base + chaininfo->counter_offset; ++ sp++; ++ continue; ++letscontinue: ++ point = (struct ebt_entry *) ++ (((char *)point) + point->next_offset); ++ i++; ++ } ++ ++ // I actually like this :) ++ if (chaininfo->policy == EBT_RETURN) ++ goto letsreturn; ++ if (chaininfo->policy == EBT_ACCEPT) { ++ read_unlock_bh(&table->lock); ++ return NF_ACCEPT; ++ } ++ read_unlock_bh(&table->lock); ++ return NF_DROP; ++} ++ ++// If it succeeds, returns element and locks mutex ++static inline void * ++find_inlist_lock_noload(struct list_head *head, const char *name, int *error, ++ struct semaphore *mutex) ++{ ++ void *ret; ++ ++ *error = down_interruptible(mutex); ++ if (*error != 0) ++ return NULL; ++ ++ ret = list_named_find(head, name); ++ if (!ret) { ++ *error = -ENOENT; ++ up(mutex); ++ } ++ return ret; ++} ++ ++#ifndef CONFIG_KMOD ++#define find_inlist_lock(h,n,p,e,m) find_inlist_lock_noload((h),(n),(e),(m)) ++#else ++static void * ++find_inlist_lock(struct list_head *head, const char *name, const char *prefix, ++ int *error, struct semaphore *mutex) ++{ ++ void *ret; ++ ++ ret = find_inlist_lock_noload(head, name, error, mutex); ++ if (!ret) { ++ char modulename[EBT_FUNCTION_MAXNAMELEN + strlen(prefix) + 1]; ++ strcpy(modulename, prefix); ++ strcat(modulename, name); ++ request_module(modulename); ++ ret = find_inlist_lock_noload(head, name, error, mutex); ++ } ++ return ret; ++} ++#endif ++ ++static inline struct ebt_table * ++find_table_lock(const char *name, int *error, struct semaphore *mutex) ++{ ++ return find_inlist_lock(&ebt_tables, name, "ebtable_", error, mutex); ++} ++ ++static inline struct ebt_match * ++find_match_lock(const char *name, int *error, struct semaphore *mutex) ++{ ++ return find_inlist_lock(&ebt_matches, name, "ebt_", error, mutex); ++} ++ ++static inline struct ebt_watcher * ++find_watcher_lock(const char *name, int *error, struct semaphore *mutex) ++{ ++ return find_inlist_lock(&ebt_watchers, name, "ebt_", error, mutex); ++} ++ ++static inline struct ebt_target * ++find_target_lock(const char *name, int *error, struct semaphore *mutex) ++{ ++ return find_inlist_lock(&ebt_targets, name, "ebt_", error, mutex); ++} ++ ++static inline int ++ebt_check_match(struct ebt_entry_match *m, struct ebt_entry *e, ++ const char *name, unsigned int hookmask, unsigned int *cnt) ++{ ++ struct ebt_match *match; ++ int ret; ++ ++ if (((char *)m) + m->match_size + sizeof(struct ebt_entry_match) > ++ ((char *)e) + e->watchers_offset) ++ return -EINVAL; ++ match = find_match_lock(m->u.name, &ret, &ebt_mutex); ++ if (!match) ++ return ret; ++ m->u.match = match; ++ if (match->me) ++ __MOD_INC_USE_COUNT(match->me); ++ up(&ebt_mutex); ++ if (match->check && ++ match->check(name, hookmask, e, m->data, m->match_size) != 0) { ++ BUGPRINT("match->check failed\n"); ++ if (match->me) ++ __MOD_DEC_USE_COUNT(match->me); ++ return -EINVAL; ++ } ++ (*cnt)++; ++ return 0; ++} ++ ++static inline int ++ebt_check_watcher(struct ebt_entry_watcher *w, struct ebt_entry *e, ++ const char *name, unsigned int hookmask, unsigned int *cnt) ++{ ++ struct ebt_watcher *watcher; ++ int ret; ++ ++ if (((char *)w) + w->watcher_size + sizeof(struct ebt_entry_watcher) > ++ ((char *)e) + e->target_offset) ++ return -EINVAL; ++ watcher = find_watcher_lock(w->u.name, &ret, &ebt_mutex); ++ if (!watcher) ++ return ret; ++ w->u.watcher = watcher; ++ if (watcher->me) ++ __MOD_INC_USE_COUNT(watcher->me); ++ up(&ebt_mutex); ++ if (watcher->check && ++ watcher->check(name, hookmask, e, w->data, w->watcher_size) != 0) { ++ BUGPRINT("watcher->check failed\n"); ++ if (watcher->me) ++ __MOD_DEC_USE_COUNT(watcher->me); ++ return -EINVAL; ++ } ++ (*cnt)++; ++ return 0; ++} ++ ++// this one is very careful, as it is the first function ++// to parse the userspace data ++static inline int ++ebt_check_entry_size_and_hooks(struct ebt_entry *e, ++ struct ebt_table_info *newinfo, char *base, char *limit, ++ struct ebt_entries **hook_entries, unsigned int *n, unsigned int *cnt, ++ unsigned int *totalcnt, unsigned int *udc_cnt, unsigned int valid_hooks) ++{ ++ int i; ++ ++ for (i = 0; i < NF_BR_NUMHOOKS; i++) { ++ if ((valid_hooks & (1 << i)) == 0) ++ continue; ++ if ( (char *)hook_entries[i] - base == ++ (char *)e - newinfo->entries) ++ break; ++ } ++ // beginning of a new chain ++ // if i == NF_BR_NUMHOOKS it must be a user defined chain ++ if (i != NF_BR_NUMHOOKS || !(e->bitmask & EBT_ENTRY_OR_ENTRIES)) { ++ if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) != 0) { ++ // we make userspace set this right, ++ // so there is no misunderstanding ++ BUGPRINT("EBT_ENTRY_OR_ENTRIES shouldn't be set " ++ "in distinguisher\n"); ++ return -EINVAL; ++ } ++ // this checks if the previous chain has as many entries ++ // as it said it has ++ if (*n != *cnt) { ++ BUGPRINT("nentries does not equal the nr of entries " ++ "in the chain\n"); ++ return -EINVAL; ++ } ++ // before we look at the struct, be sure it is not too big ++ if ((char *)hook_entries[i] + sizeof(struct ebt_entries) ++ > limit) { ++ BUGPRINT("entries_size too small\n"); ++ return -EINVAL; ++ } ++ if (((struct ebt_entries *)e)->policy != EBT_DROP && ++ ((struct ebt_entries *)e)->policy != EBT_ACCEPT) { ++ // only RETURN from udc ++ if (i != NF_BR_NUMHOOKS || ++ ((struct ebt_entries *)e)->policy != EBT_RETURN) { ++ BUGPRINT("bad policy\n"); ++ return -EINVAL; ++ } ++ } ++ if (i == NF_BR_NUMHOOKS) // it's a user defined chain ++ (*udc_cnt)++; ++ else ++ newinfo->hook_entry[i] = (struct ebt_entries *)e; ++ if (((struct ebt_entries *)e)->counter_offset != *totalcnt) { ++ BUGPRINT("counter_offset != totalcnt"); ++ return -EINVAL; ++ } ++ *n = ((struct ebt_entries *)e)->nentries; ++ *cnt = 0; ++ return 0; ++ } ++ // a plain old entry, heh ++ if (sizeof(struct ebt_entry) > e->watchers_offset || ++ e->watchers_offset > e->target_offset || ++ e->target_offset >= e->next_offset) { ++ BUGPRINT("entry offsets not in right order\n"); ++ return -EINVAL; ++ } ++ // this is not checked anywhere else ++ if (e->next_offset - e->target_offset < sizeof(struct ebt_entry_target)) { ++ BUGPRINT("target size too small\n"); ++ return -EINVAL; ++ } ++ ++ (*cnt)++; ++ (*totalcnt)++; ++ return 0; ++} ++ ++struct ebt_cl_stack ++{ ++ struct ebt_chainstack cs; ++ int from; ++ unsigned int hookmask; ++}; ++ ++// we need these positions to check that the jumps to a different part of the ++// entries is a jump to the beginning of a new chain. ++static inline int ++ebt_get_udc_positions(struct ebt_entry *e, struct ebt_table_info *newinfo, ++ struct ebt_entries **hook_entries, unsigned int *n, unsigned int valid_hooks, ++ struct ebt_cl_stack *udc) ++{ ++ int i; ++ ++ // we're only interested in chain starts ++ if (e->bitmask & EBT_ENTRY_OR_ENTRIES) ++ return 0; ++ for (i = 0; i < NF_BR_NUMHOOKS; i++) { ++ if ((valid_hooks & (1 << i)) == 0) ++ continue; ++ if (newinfo->hook_entry[i] == (struct ebt_entries *)e) ++ break; ++ } ++ // only care about udc ++ if (i != NF_BR_NUMHOOKS) ++ return 0; ++ ++ udc[*n].cs.chaininfo = (struct ebt_entries *)e; ++ // these initialisations are depended on later in check_chainloops() ++ udc[*n].cs.n = 0; ++ udc[*n].hookmask = 0; ++ ++ (*n)++; ++ return 0; ++} ++ ++static inline int ++ebt_cleanup_match(struct ebt_entry_match *m, unsigned int *i) ++{ ++ if (i && (*i)-- == 0) ++ return 1; ++ if (m->u.match->destroy) ++ m->u.match->destroy(m->data, m->match_size); ++ if (m->u.match->me) ++ __MOD_DEC_USE_COUNT(m->u.match->me); ++ ++ return 0; ++} ++ ++static inline int ++ebt_cleanup_watcher(struct ebt_entry_watcher *w, unsigned int *i) ++{ ++ if (i && (*i)-- == 0) ++ return 1; ++ if (w->u.watcher->destroy) ++ w->u.watcher->destroy(w->data, w->watcher_size); ++ if (w->u.watcher->me) ++ __MOD_DEC_USE_COUNT(w->u.watcher->me); ++ ++ return 0; ++} ++ ++static inline int ++ebt_cleanup_entry(struct ebt_entry *e, unsigned int *cnt) ++{ ++ struct ebt_entry_target *t; ++ ++ if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) ++ return 0; ++ // we're done ++ if (cnt && (*cnt)-- == 0) ++ return 1; ++ EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, NULL); ++ EBT_MATCH_ITERATE(e, ebt_cleanup_match, NULL); ++ t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); ++ if (t->u.target->destroy) ++ t->u.target->destroy(t->data, t->target_size); ++ if (t->u.target->me) ++ __MOD_DEC_USE_COUNT(t->u.target->me); ++ ++ return 0; ++} ++ ++static inline int ++ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, ++ const char *name, unsigned int *cnt, unsigned int valid_hooks, ++ struct ebt_cl_stack *cl_s, unsigned int udc_cnt) ++{ ++ struct ebt_entry_target *t; ++ struct ebt_target *target; ++ unsigned int i, j, hook = 0, hookmask = 0; ++ int ret; ++ ++ // Don't mess with the struct ebt_entries ++ if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) ++ return 0; ++ ++ if (e->bitmask & ~EBT_F_MASK) { ++ BUGPRINT("Unknown flag for bitmask\n"); ++ return -EINVAL; ++ } ++ if (e->invflags & ~EBT_INV_MASK) { ++ BUGPRINT("Unknown flag for inv bitmask\n"); ++ return -EINVAL; ++ } ++ if ( (e->bitmask & EBT_NOPROTO) && (e->bitmask & EBT_802_3) ) { ++ BUGPRINT("NOPROTO & 802_3 not allowed\n"); ++ return -EINVAL; ++ } ++ // what hook do we belong to? ++ for (i = 0; i < NF_BR_NUMHOOKS; i++) { ++ if ((valid_hooks & (1 << i)) == 0) ++ continue; ++ if ((char *)newinfo->hook_entry[i] < (char *)e) ++ hook = i; ++ else ++ break; ++ } ++ // (1 << NF_BR_NUMHOOKS) tells the check functions the rule is on ++ // a base chain ++ if (i < NF_BR_NUMHOOKS) ++ hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS); ++ else { ++ for (i = 0; i < udc_cnt; i++) ++ if ((char *)(cl_s[i].cs.chaininfo) > (char *)e) ++ break; ++ if (i == 0) ++ hookmask = (1 << hook) | (1 << NF_BR_NUMHOOKS); ++ else ++ hookmask = cl_s[i - 1].hookmask; ++ } ++ i = 0; ++ ret = EBT_MATCH_ITERATE(e, ebt_check_match, e, name, hookmask, &i); ++ if (ret != 0) ++ goto cleanup_matches; ++ j = 0; ++ ret = EBT_WATCHER_ITERATE(e, ebt_check_watcher, e, name, hookmask, &j); ++ if (ret != 0) ++ goto cleanup_watchers; ++ t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); ++ target = find_target_lock(t->u.name, &ret, &ebt_mutex); ++ if (!target) ++ goto cleanup_watchers; ++ if (target->me) ++ __MOD_INC_USE_COUNT(target->me); ++ up(&ebt_mutex); ++ ++ t->u.target = target; ++ if (t->u.target == &ebt_standard_target) { ++ if (e->target_offset + sizeof(struct ebt_standard_target) > ++ e->next_offset) { ++ BUGPRINT("Standard target size too big\n"); ++ ret = -EFAULT; ++ goto cleanup_watchers; ++ } ++ if (((struct ebt_standard_target *)t)->verdict < ++ -NUM_STANDARD_TARGETS) { ++ BUGPRINT("Invalid standard target\n"); ++ ret = -EFAULT; ++ goto cleanup_watchers; ++ } ++ } else if ((e->target_offset + t->target_size + ++ sizeof(struct ebt_entry_target) > e->next_offset) || ++ (t->u.target->check && ++ t->u.target->check(name, hookmask, e, t->data, t->target_size) != 0)){ ++ if (t->u.target->me) ++ __MOD_DEC_USE_COUNT(t->u.target->me); ++ ret = -EFAULT; ++ goto cleanup_watchers; ++ } ++ (*cnt)++; ++ return 0; ++cleanup_watchers: ++ EBT_WATCHER_ITERATE(e, ebt_cleanup_watcher, &j); ++cleanup_matches: ++ EBT_MATCH_ITERATE(e, ebt_cleanup_match, &i); ++ return ret; ++} ++ ++// checks for loops and sets the hook mask for udc ++// the hook mask for udc tells us from which base chains the udc can be ++// accessed. This mask is a parameter to the check() functions of the extensions ++static int check_chainloops(struct ebt_entries *chain, ++ struct ebt_cl_stack *cl_s, unsigned int udc_cnt, ++ unsigned int hooknr, char *base) ++{ ++ int i, chain_nr = -1, pos = 0, nentries = chain->nentries, verdict; ++ struct ebt_entry *e = (struct ebt_entry *)chain->data; ++ struct ebt_entry_target *t; ++ ++ while (pos < nentries || chain_nr != -1) { ++ // end of udc, go back one 'recursion' step ++ if (pos == nentries) { ++ // put back values of the time when this chain was called ++ e = cl_s[chain_nr].cs.e; ++ if (cl_s[chain_nr].from != -1) ++ nentries = ++ cl_s[cl_s[chain_nr].from].cs.chaininfo->nentries; ++ else ++ nentries = chain->nentries; ++ pos = cl_s[chain_nr].cs.n; ++ // make sure we won't see a loop that isn't one ++ cl_s[chain_nr].cs.n = 0; ++ chain_nr = cl_s[chain_nr].from; ++ if (pos == nentries) ++ continue; ++ } ++ t = (struct ebt_entry_target *) ++ (((char *)e) + e->target_offset); ++ if (strcmp(t->u.name, EBT_STANDARD_TARGET)) ++ goto letscontinue; ++ if (e->target_offset + sizeof(struct ebt_standard_target) > ++ e->next_offset) { ++ BUGPRINT("Standard target size too big\n"); ++ return -1; ++ } ++ verdict = ((struct ebt_standard_target *)t)->verdict; ++ if (verdict >= 0) { // jump to another chain ++ struct ebt_entries *hlp2 = ++ (struct ebt_entries *)(base + verdict); ++ for (i = 0; i < udc_cnt; i++) ++ if (hlp2 == cl_s[i].cs.chaininfo) ++ break; ++ // bad destination or loop ++ if (i == udc_cnt) { ++ BUGPRINT("bad destination\n"); ++ return -1; ++ } ++ if (cl_s[i].cs.n) { ++ BUGPRINT("loop\n"); ++ return -1; ++ } ++ // this can't be 0, so the above test is correct ++ cl_s[i].cs.n = pos + 1; ++ pos = 0; ++ cl_s[i].cs.e = ((void *)e + e->next_offset); ++ e = (struct ebt_entry *)(hlp2->data); ++ nentries = hlp2->nentries; ++ cl_s[i].from = chain_nr; ++ chain_nr = i; ++ // this udc is accessible from the base chain for hooknr ++ cl_s[i].hookmask |= (1 << hooknr); ++ continue; ++ } ++letscontinue: ++ e = (void *)e + e->next_offset; ++ pos++; ++ } ++ return 0; ++} ++ ++// do the parsing of the table/chains/entries/matches/watchers/targets, heh ++static int translate_table(struct ebt_replace *repl, ++ struct ebt_table_info *newinfo) ++{ ++ unsigned int i, j, k, udc_cnt; ++ int ret; ++ struct ebt_cl_stack *cl_s = NULL; // used in the checking for chain loops ++ ++ i = 0; ++ while (i < NF_BR_NUMHOOKS && !(repl->valid_hooks & (1 << i))) ++ i++; ++ if (i == NF_BR_NUMHOOKS) { ++ BUGPRINT("No valid hooks specified\n"); ++ return -EINVAL; ++ } ++ if (repl->hook_entry[i] != (struct ebt_entries *)repl->entries) { ++ BUGPRINT("Chains don't start at beginning\n"); ++ return -EINVAL; ++ } ++ // make sure chains are ordered after each other in same order ++ // as their corresponding hooks ++ for (j = i + 1; j < NF_BR_NUMHOOKS; j++) { ++ if (!(repl->valid_hooks & (1 << j))) ++ continue; ++ if ( repl->hook_entry[j] <= repl->hook_entry[i] ) { ++ BUGPRINT("Hook order must be followed\n"); ++ return -EINVAL; ++ } ++ i = j; ++ } ++ ++ for (i = 0; i < NF_BR_NUMHOOKS; i++) ++ newinfo->hook_entry[i] = NULL; ++ ++ newinfo->entries_size = repl->entries_size; ++ newinfo->nentries = repl->nentries; ++ ++ // do some early checkings and initialize some things ++ i = 0; // holds the expected nr. of entries for the chain ++ j = 0; // holds the up to now counted entries for the chain ++ k = 0; // holds the total nr. of entries, should equal ++ // newinfo->nentries afterwards ++ udc_cnt = 0; // will hold the nr. of user defined chains (udc) ++ ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, ++ ebt_check_entry_size_and_hooks, newinfo, repl->entries, ++ repl->entries + repl->entries_size, repl->hook_entry, &i, &j, &k, ++ &udc_cnt, repl->valid_hooks); ++ ++ if (ret != 0) ++ return ret; ++ ++ if (i != j) { ++ BUGPRINT("nentries does not equal the nr of entries in the " ++ "(last) chain\n"); ++ return -EINVAL; ++ } ++ if (k != newinfo->nentries) { ++ BUGPRINT("Total nentries is wrong\n"); ++ return -EINVAL; ++ } ++ ++ // check if all valid hooks have a chain ++ for (i = 0; i < NF_BR_NUMHOOKS; i++) { ++ if (newinfo->hook_entry[i] == NULL && ++ (repl->valid_hooks & (1 << i))) { ++ BUGPRINT("Valid hook without chain\n"); ++ return -EINVAL; ++ } ++ } ++ ++ // Get the location of the udc, put them in an array ++ // While we're at it, allocate the chainstack ++ if (udc_cnt) { ++ // this will get free'd in do_replace()/ebt_register_table() ++ // if an error occurs ++ newinfo->chainstack = (struct ebt_chainstack **) ++ vmalloc(smp_num_cpus * sizeof(struct ebt_chainstack)); ++ if (!newinfo->chainstack) ++ return -ENOMEM; ++ for (i = 0; i < smp_num_cpus; i++) { ++ newinfo->chainstack[i] = ++ vmalloc(udc_cnt * sizeof(struct ebt_chainstack)); ++ if (!newinfo->chainstack[i]) { ++ while (i) ++ vfree(newinfo->chainstack[--i]); ++ vfree(newinfo->chainstack); ++ newinfo->chainstack = NULL; ++ return -ENOMEM; ++ } ++ } ++ ++ cl_s = (struct ebt_cl_stack *) ++ vmalloc(udc_cnt * sizeof(struct ebt_cl_stack)); ++ if (!cl_s) ++ return -ENOMEM; ++ i = 0; // the i'th udc ++ EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, ++ ebt_get_udc_positions, newinfo, repl->hook_entry, &i, ++ repl->valid_hooks, cl_s); ++ // sanity check ++ if (i != udc_cnt) { ++ BUGPRINT("i != udc_cnt\n"); ++ vfree(cl_s); ++ return -EFAULT; ++ } ++ } ++ ++ // Check for loops ++ for (i = 0; i < NF_BR_NUMHOOKS; i++) ++ if (repl->valid_hooks & (1 << i)) ++ if (check_chainloops(newinfo->hook_entry[i], ++ cl_s, udc_cnt, i, newinfo->entries)) { ++ if (cl_s) ++ vfree(cl_s); ++ return -EINVAL; ++ } ++ ++ // we now know the following (along with E=mc²): ++ // - the nr of entries in each chain is right ++ // - the size of the allocated space is right ++ // - all valid hooks have a corresponding chain ++ // - there are no loops ++ // - wrong data can still be on the level of a single entry ++ // - could be there are jumps to places that are not the ++ // beginning of a chain. This can only occur in chains that ++ // are not accessible from any base chains, so we don't care. ++ ++ // used to know what we need to clean up if something goes wrong ++ i = 0; ++ ret = EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, ++ ebt_check_entry, newinfo, repl->name, &i, repl->valid_hooks, ++ cl_s, udc_cnt); ++ if (ret != 0) { ++ EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, ++ ebt_cleanup_entry, &i); ++ } ++ if (cl_s) ++ vfree(cl_s); ++ return ret; ++} ++ ++// called under write_lock ++static void get_counters(struct ebt_counter *oldcounters, ++ struct ebt_counter *counters, unsigned int nentries) ++{ ++ int i, cpu; ++ struct ebt_counter *counter_base; ++ ++ // counters of cpu 0 ++ memcpy(counters, oldcounters, ++ sizeof(struct ebt_counter) * nentries); ++ // add other counters to those of cpu 0 ++ for (cpu = 1; cpu < smp_num_cpus; cpu++) { ++ counter_base = COUNTER_BASE(oldcounters, nentries, cpu); ++ for (i = 0; i < nentries; i++) { ++ counters[i].pcnt += counter_base[i].pcnt; ++ counters[i].bcnt += counter_base[i].bcnt; ++ } ++ } ++} ++ ++// replace the table ++static int do_replace(void *user, unsigned int len) ++{ ++ int ret, i, countersize; ++ struct ebt_table_info *newinfo; ++ struct ebt_replace tmp; ++ struct ebt_table *t; ++ struct ebt_counter *counterstmp = NULL; ++ // used to be able to unlock earlier ++ struct ebt_table_info *table; ++ ++ if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) ++ return -EFAULT; ++ ++ if (len != sizeof(tmp) + tmp.entries_size) { ++ BUGPRINT("Wrong len argument\n"); ++ return -EINVAL; ++ } ++ ++ if (tmp.entries_size == 0) { ++ BUGPRINT("Entries_size never zero\n"); ++ return -EINVAL; ++ } ++ countersize = COUNTER_OFFSET(tmp.nentries) * smp_num_cpus; ++ newinfo = (struct ebt_table_info *) ++ vmalloc(sizeof(struct ebt_table_info) + countersize); ++ if (!newinfo) ++ return -ENOMEM; ++ ++ if (countersize) ++ memset(newinfo->counters, 0, countersize); ++ ++ newinfo->entries = (char *)vmalloc(tmp.entries_size); ++ if (!newinfo->entries) { ++ ret = -ENOMEM; ++ goto free_newinfo; ++ } ++ if (copy_from_user( ++ newinfo->entries, tmp.entries, tmp.entries_size) != 0) { ++ BUGPRINT("Couldn't copy entries from userspace\n"); ++ ret = -EFAULT; ++ goto free_entries; ++ } ++ ++ // the user wants counters back ++ // the check on the size is done later, when we have the lock ++ if (tmp.num_counters) { ++ counterstmp = (struct ebt_counter *) ++ vmalloc(tmp.num_counters * sizeof(struct ebt_counter)); ++ if (!counterstmp) { ++ ret = -ENOMEM; ++ goto free_entries; ++ } ++ } ++ else ++ counterstmp = NULL; ++ ++ // this can get initialized by translate_table() ++ newinfo->chainstack = NULL; ++ ret = translate_table(&tmp, newinfo); ++ ++ if (ret != 0) ++ goto free_counterstmp; ++ ++ t = find_table_lock(tmp.name, &ret, &ebt_mutex); ++ if (!t) ++ goto free_iterate; ++ ++ // the table doesn't like it ++ if (t->check && (ret = t->check(newinfo, tmp.valid_hooks))) ++ goto free_unlock; ++ ++ if (tmp.num_counters && tmp.num_counters != t->private->nentries) { ++ BUGPRINT("Wrong nr. of counters requested\n"); ++ ret = -EINVAL; ++ goto free_unlock; ++ } ++ ++ // we have the mutex lock, so no danger in reading this pointer ++ table = t->private; ++ // we need an atomic snapshot of the counters ++ write_lock_bh(&t->lock); ++ if (tmp.num_counters) ++ get_counters(t->private->counters, counterstmp, ++ t->private->nentries); ++ ++ t->private = newinfo; ++ write_unlock_bh(&t->lock); ++ up(&ebt_mutex); ++ // So, a user can change the chains while having messed up her counter ++ // allocation. Only reason why this is done is because this way the lock ++ // is held only once, while this doesn't bring the kernel into a ++ // dangerous state. ++ if (tmp.num_counters && ++ copy_to_user(tmp.counters, counterstmp, ++ tmp.num_counters * sizeof(struct ebt_counter))) { ++ BUGPRINT("Couldn't copy counters to userspace\n"); ++ ret = -EFAULT; ++ } ++ else ++ ret = 0; ++ ++ // decrease module count and free resources ++ EBT_ENTRY_ITERATE(table->entries, table->entries_size, ++ ebt_cleanup_entry, NULL); ++ ++ vfree(table->entries); ++ if (table->chainstack) { ++ for (i = 0; i < smp_num_cpus; i++) ++ vfree(table->chainstack[i]); ++ vfree(table->chainstack); ++ } ++ vfree(table); ++ ++ if (counterstmp) ++ vfree(counterstmp); ++ return ret; ++ ++free_unlock: ++ up(&ebt_mutex); ++free_iterate: ++ EBT_ENTRY_ITERATE(newinfo->entries, newinfo->entries_size, ++ ebt_cleanup_entry, NULL); ++free_counterstmp: ++ if (counterstmp) ++ vfree(counterstmp); ++ // can be initialized in translate_table() ++ if (newinfo->chainstack) { ++ for (i = 0; i < smp_num_cpus; i++) ++ vfree(newinfo->chainstack[i]); ++ vfree(newinfo->chainstack); ++ } ++free_entries: ++ if (newinfo->entries) ++ vfree(newinfo->entries); ++free_newinfo: ++ if (newinfo) ++ vfree(newinfo); ++ return ret; ++} ++ ++int ebt_register_target(struct ebt_target *target) ++{ ++ int ret; ++ ++ ret = down_interruptible(&ebt_mutex); ++ if (ret != 0) ++ return ret; ++ if (!list_named_insert(&ebt_targets, target)) { ++ up(&ebt_mutex); ++ return -EEXIST; ++ } ++ up(&ebt_mutex); ++ MOD_INC_USE_COUNT; ++ ++ return 0; ++} ++ ++void ebt_unregister_target(struct ebt_target *target) ++{ ++ down(&ebt_mutex); ++ LIST_DELETE(&ebt_targets, target); ++ up(&ebt_mutex); ++ MOD_DEC_USE_COUNT; ++} ++ ++int ebt_register_match(struct ebt_match *match) ++{ ++ int ret; ++ ++ ret = down_interruptible(&ebt_mutex); ++ if (ret != 0) ++ return ret; ++ if (!list_named_insert(&ebt_matches, match)) { ++ up(&ebt_mutex); ++ return -EEXIST; ++ } ++ up(&ebt_mutex); ++ MOD_INC_USE_COUNT; ++ ++ return 0; ++} ++ ++void ebt_unregister_match(struct ebt_match *match) ++{ ++ down(&ebt_mutex); ++ LIST_DELETE(&ebt_matches, match); ++ up(&ebt_mutex); ++ MOD_DEC_USE_COUNT; ++} ++ ++int ebt_register_watcher(struct ebt_watcher *watcher) ++{ ++ int ret; ++ ++ ret = down_interruptible(&ebt_mutex); ++ if (ret != 0) ++ return ret; ++ if (!list_named_insert(&ebt_watchers, watcher)) { ++ up(&ebt_mutex); ++ return -EEXIST; ++ } ++ up(&ebt_mutex); ++ MOD_INC_USE_COUNT; ++ ++ return 0; ++} ++ ++void ebt_unregister_watcher(struct ebt_watcher *watcher) ++{ ++ down(&ebt_mutex); ++ LIST_DELETE(&ebt_watchers, watcher); ++ up(&ebt_mutex); ++ MOD_DEC_USE_COUNT; ++} ++ ++int ebt_register_table(struct ebt_table *table) ++{ ++ struct ebt_table_info *newinfo; ++ int ret, i, countersize; ++ ++ if (!table || !table->table ||!table->table->entries || ++ table->table->entries_size == 0 || ++ table->table->counters || table->private) { ++ BUGPRINT("Bad table data for ebt_register_table!!!\n"); ++ return -EINVAL; ++ } ++ ++ countersize = COUNTER_OFFSET(table->table->nentries) * smp_num_cpus; ++ newinfo = (struct ebt_table_info *) ++ vmalloc(sizeof(struct ebt_table_info) + countersize); ++ ret = -ENOMEM; ++ if (!newinfo) ++ return -ENOMEM; ++ ++ newinfo->entries = (char *)vmalloc(table->table->entries_size); ++ if (!(newinfo->entries)) ++ goto free_newinfo; ++ ++ memcpy(newinfo->entries, table->table->entries, ++ table->table->entries_size); ++ ++ if (countersize) ++ memset(newinfo->counters, 0, countersize); ++ ++ // fill in newinfo and parse the entries ++ newinfo->chainstack = NULL; ++ ret = translate_table(table->table, newinfo); ++ if (ret != 0) { ++ BUGPRINT("Translate_table failed\n"); ++ goto free_chainstack; ++ } ++ ++ if (table->check && table->check(newinfo, table->valid_hooks)) { ++ BUGPRINT("The table doesn't like its own initial data, lol\n"); ++ return -EINVAL; ++ } ++ ++ table->private = newinfo; ++ table->lock = RW_LOCK_UNLOCKED; ++ ret = down_interruptible(&ebt_mutex); ++ if (ret != 0) ++ goto free_chainstack; ++ ++ if (list_named_find(&ebt_tables, table->name)) { ++ ret = -EEXIST; ++ BUGPRINT("Table name already exists\n"); ++ goto free_unlock; ++ } ++ ++ list_prepend(&ebt_tables, table); ++ up(&ebt_mutex); ++ MOD_INC_USE_COUNT; ++ return 0; ++free_unlock: ++ up(&ebt_mutex); ++free_chainstack: ++ if (newinfo->chainstack) { ++ for (i = 0; i < smp_num_cpus; i++) ++ vfree(newinfo->chainstack[i]); ++ vfree(newinfo->chainstack); ++ } ++ vfree(newinfo->entries); ++free_newinfo: ++ vfree(newinfo); ++ return ret; ++} ++ ++void ebt_unregister_table(struct ebt_table *table) ++{ ++ int i; ++ ++ if (!table) { ++ BUGPRINT("Request to unregister NULL table!!!\n"); ++ return; ++ } ++ down(&ebt_mutex); ++ LIST_DELETE(&ebt_tables, table); ++ up(&ebt_mutex); ++ EBT_ENTRY_ITERATE(table->private->entries, ++ table->private->entries_size, ebt_cleanup_entry, NULL); ++ if (table->private->entries) ++ vfree(table->private->entries); ++ if (table->private->chainstack) { ++ for (i = 0; i < smp_num_cpus; i++) ++ vfree(table->private->chainstack[i]); ++ vfree(table->private->chainstack); ++ } ++ vfree(table->private); ++ MOD_DEC_USE_COUNT; ++} ++ ++// userspace just supplied us with counters ++static int update_counters(void *user, unsigned int len) ++{ ++ int i, ret; ++ struct ebt_counter *tmp; ++ struct ebt_replace hlp; ++ struct ebt_table *t; ++ ++ if (copy_from_user(&hlp, user, sizeof(hlp))) ++ return -EFAULT; ++ ++ if (len != sizeof(hlp) + hlp.num_counters * sizeof(struct ebt_counter)) ++ return -EINVAL; ++ if (hlp.num_counters == 0) ++ return -EINVAL; ++ ++ if ( !(tmp = (struct ebt_counter *) ++ vmalloc(hlp.num_counters * sizeof(struct ebt_counter))) ){ ++ MEMPRINT("Update_counters && nomemory\n"); ++ return -ENOMEM; ++ } ++ ++ t = find_table_lock(hlp.name, &ret, &ebt_mutex); ++ if (!t) ++ goto free_tmp; ++ ++ if (hlp.num_counters != t->private->nentries) { ++ BUGPRINT("Wrong nr of counters\n"); ++ ret = -EINVAL; ++ goto unlock_mutex; ++ } ++ ++ if ( copy_from_user(tmp, hlp.counters, ++ hlp.num_counters * sizeof(struct ebt_counter)) ) { ++ BUGPRINT("Updata_counters && !cfu\n"); ++ ret = -EFAULT; ++ goto unlock_mutex; ++ } ++ ++ // we want an atomic add of the counters ++ write_lock_bh(&t->lock); ++ ++ // we add to the counters of the first cpu ++ for (i = 0; i < hlp.num_counters; i++) { ++ t->private->counters[i].pcnt += tmp[i].pcnt; ++ t->private->counters[i].bcnt += tmp[i].bcnt; ++ } ++ ++ write_unlock_bh(&t->lock); ++ ret = 0; ++unlock_mutex: ++ up(&ebt_mutex); ++free_tmp: ++ vfree(tmp); ++ return ret; ++} ++ ++static inline int ebt_make_matchname(struct ebt_entry_match *m, ++ char *base, char *ubase) ++{ ++ char *hlp = ubase - base + (char *)m; ++ if (copy_to_user(hlp, m->u.match->name, EBT_FUNCTION_MAXNAMELEN)) ++ return -EFAULT; ++ return 0; ++} ++ ++static inline int ebt_make_watchername(struct ebt_entry_watcher *w, ++ char *base, char *ubase) ++{ ++ char *hlp = ubase - base + (char *)w; ++ if (copy_to_user(hlp , w->u.watcher->name, EBT_FUNCTION_MAXNAMELEN)) ++ return -EFAULT; ++ return 0; ++} ++ ++static inline int ebt_make_names(struct ebt_entry *e, char *base, char *ubase) ++{ ++ int ret; ++ char *hlp; ++ struct ebt_entry_target *t; ++ ++ if ((e->bitmask & EBT_ENTRY_OR_ENTRIES) == 0) ++ return 0; ++ ++ hlp = ubase - base + (char *)e + e->target_offset; ++ t = (struct ebt_entry_target *)(((char *)e) + e->target_offset); ++ ++ ret = EBT_MATCH_ITERATE(e, ebt_make_matchname, base, ubase); ++ if (ret != 0) ++ return ret; ++ ret = EBT_WATCHER_ITERATE(e, ebt_make_watchername, base, ubase); ++ if (ret != 0) ++ return ret; ++ if (copy_to_user(hlp, t->u.target->name, EBT_FUNCTION_MAXNAMELEN)) ++ return -EFAULT; ++ return 0; ++} ++ ++// called with ebt_mutex down ++static int copy_everything_to_user(struct ebt_table *t, void *user, ++ int *len, int cmd) ++{ ++ struct ebt_replace tmp; ++ struct ebt_counter *counterstmp, *oldcounters; ++ unsigned int entries_size, nentries; ++ char *entries; ++ ++ if (cmd == EBT_SO_GET_ENTRIES) { ++ entries_size = t->private->entries_size; ++ nentries = t->private->nentries; ++ entries = t->private->entries; ++ oldcounters = t->private->counters; ++ } else { ++ entries_size = t->table->entries_size; ++ nentries = t->table->nentries; ++ entries = t->table->entries; ++ oldcounters = t->table->counters; ++ } ++ ++ if (copy_from_user(&tmp, user, sizeof(tmp))) { ++ BUGPRINT("Cfu didn't work\n"); ++ return -EFAULT; ++ } ++ ++ if (*len != sizeof(struct ebt_replace) + entries_size + ++ (tmp.num_counters? nentries * sizeof(struct ebt_counter): 0)) { ++ BUGPRINT("Wrong size\n"); ++ return -EINVAL; ++ } ++ ++ if (tmp.nentries != nentries) { ++ BUGPRINT("Nentries wrong\n"); ++ return -EINVAL; ++ } ++ ++ if (tmp.entries_size != entries_size) { ++ BUGPRINT("Wrong size\n"); ++ return -EINVAL; ++ } ++ ++ // userspace might not need the counters ++ if (tmp.num_counters) { ++ if (tmp.num_counters != nentries) { ++ BUGPRINT("Num_counters wrong\n"); ++ return -EINVAL; ++ } ++ counterstmp = (struct ebt_counter *) ++ vmalloc(nentries * sizeof(struct ebt_counter)); ++ if (!counterstmp) { ++ MEMPRINT("Couldn't copy counters, out of memory\n"); ++ return -ENOMEM; ++ } ++ write_lock_bh(&t->lock); ++ get_counters(oldcounters, counterstmp, nentries); ++ write_unlock_bh(&t->lock); ++ ++ if (copy_to_user(tmp.counters, counterstmp, ++ nentries * sizeof(struct ebt_counter))) { ++ BUGPRINT("Couldn't copy counters to userspace\n"); ++ vfree(counterstmp); ++ return -EFAULT; ++ } ++ vfree(counterstmp); ++ } ++ ++ if (copy_to_user(tmp.entries, entries, entries_size)) { ++ BUGPRINT("Couldn't copy entries to userspace\n"); ++ return -EFAULT; ++ } ++ // set the match/watcher/target names right ++ return EBT_ENTRY_ITERATE(entries, entries_size, ++ ebt_make_names, entries, tmp.entries); ++} ++ ++static int do_ebt_set_ctl(struct sock *sk, ++ int cmd, void *user, unsigned int len) ++{ ++ int ret; ++ ++ switch(cmd) { ++ case EBT_SO_SET_ENTRIES: ++ ret = do_replace(user, len); ++ break; ++ case EBT_SO_SET_COUNTERS: ++ ret = update_counters(user, len); ++ break; ++ default: ++ ret = -EINVAL; ++ } ++ return ret; ++} ++ ++static int do_ebt_get_ctl(struct sock *sk, int cmd, void *user, int *len) ++{ ++ int ret; ++ struct ebt_replace tmp; ++ struct ebt_table *t; ++ ++ if (copy_from_user(&tmp, user, sizeof(tmp))) ++ return -EFAULT; ++ ++ t = find_table_lock(tmp.name, &ret, &ebt_mutex); ++ if (!t) ++ return ret; ++ ++ switch(cmd) { ++ case EBT_SO_GET_INFO: ++ case EBT_SO_GET_INIT_INFO: ++ if (*len != sizeof(struct ebt_replace)){ ++ ret = -EINVAL; ++ up(&ebt_mutex); ++ break; ++ } ++ if (cmd == EBT_SO_GET_INFO) { ++ tmp.nentries = t->private->nentries; ++ tmp.entries_size = t->private->entries_size; ++ tmp.valid_hooks = t->valid_hooks; ++ } else { ++ tmp.nentries = t->table->nentries; ++ tmp.entries_size = t->table->entries_size; ++ tmp.valid_hooks = t->table->valid_hooks; ++ } ++ up(&ebt_mutex); ++ if (copy_to_user(user, &tmp, *len) != 0){ ++ BUGPRINT("c2u Didn't work\n"); ++ ret = -EFAULT; ++ break; ++ } ++ ret = 0; ++ break; ++ ++ case EBT_SO_GET_ENTRIES: ++ case EBT_SO_GET_INIT_ENTRIES: ++ ret = copy_everything_to_user(t, user, len, cmd); ++ up(&ebt_mutex); ++ break; ++ ++ default: ++ up(&ebt_mutex); ++ ret = -EINVAL; ++ } ++ ++ return ret; ++} ++ ++static struct nf_sockopt_ops ebt_sockopts = ++{ { NULL, NULL }, PF_INET, EBT_BASE_CTL, EBT_SO_SET_MAX + 1, do_ebt_set_ctl, ++ EBT_BASE_CTL, EBT_SO_GET_MAX + 1, do_ebt_get_ctl, 0, NULL ++}; ++ ++static int __init init(void) ++{ ++ int ret; ++ ++ down(&ebt_mutex); ++ list_named_insert(&ebt_targets, &ebt_standard_target); ++ up(&ebt_mutex); ++ if ((ret = nf_register_sockopt(&ebt_sockopts)) < 0) ++ return ret; ++ ++ printk(KERN_NOTICE "Ebtables v2.0 registered\n"); ++ return 0; ++} ++ ++static void __exit fini(void) ++{ ++ nf_unregister_sockopt(&ebt_sockopts); ++ printk(KERN_NOTICE "Ebtables v2.0 unregistered\n"); ++} ++ ++EXPORT_SYMBOL(ebt_register_table); ++EXPORT_SYMBOL(ebt_unregister_table); ++EXPORT_SYMBOL(ebt_register_match); ++EXPORT_SYMBOL(ebt_unregister_match); ++EXPORT_SYMBOL(ebt_register_watcher); ++EXPORT_SYMBOL(ebt_unregister_watcher); ++EXPORT_SYMBOL(ebt_register_target); ++EXPORT_SYMBOL(ebt_unregister_target); ++EXPORT_SYMBOL(ebt_do_table); ++module_init(init); ++module_exit(fini); ++MODULE_LICENSE("GPL"); +diff -Nurb src/linux/linux.stock/net/core/dev.c src/linux/linux/net/core/dev.c +--- src/linux/linux.stock/net/core/dev.c 2003-10-14 04:02:55.000000000 -0400 ++++ src/linux/linux/net/core/dev.c 2004-07-10 23:46:39.000000000 -0400 +@@ -1393,7 +1393,7 @@ + + + #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) +-void (*br_handle_frame_hook)(struct sk_buff *skb) = NULL; ++int (*br_handle_frame_hook)(struct sk_buff *skb) = NULL; + #endif + + static __inline__ int handle_bridge(struct sk_buff *skb, +@@ -1410,7 +1410,6 @@ + } + } + +- br_handle_frame_hook(skb); + return ret; + } + +@@ -1470,7 +1469,12 @@ + #if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) + if (skb->dev->br_port != NULL && + br_handle_frame_hook != NULL) { +- return handle_bridge(skb, pt_prev); ++ int ret; ++ ++ ret = handle_bridge(skb, pt_prev); ++ if (br_handle_frame_hook(skb) == 0) ++ return ret; ++ pt_prev = NULL; + } + #endif + +diff -Nurb src/linux/linux.stock/net/core/netfilter.c src/linux/linux/net/core/netfilter.c +--- src/linux/linux.stock/net/core/netfilter.c 2004-07-10 23:29:56.000000000 -0400 ++++ src/linux/linux/net/core/netfilter.c 2004-07-10 23:46:39.000000000 -0400 +@@ -344,10 +344,15 @@ + const struct net_device *indev, + const struct net_device *outdev, + struct list_head **i, +- int (*okfn)(struct sk_buff *)) ++ int (*okfn)(struct sk_buff *), ++ int hook_thresh) + { + for (*i = (*i)->next; *i != head; *i = (*i)->next) { + struct nf_hook_ops *elem = (struct nf_hook_ops *)*i; ++ ++ if (hook_thresh > elem->priority) ++ continue; ++ + switch (elem->hook(hook, skb, indev, outdev, okfn)) { + case NF_QUEUE: + return NF_QUEUE; +@@ -415,6 +420,10 @@ + { + int status; + struct nf_info *info; ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ struct net_device *physindev = NULL; ++ struct net_device *physoutdev = NULL; ++#endif + + if (!queue_handler[pf].outfn) { + kfree_skb(skb); +@@ -437,11 +446,24 @@ + if (indev) dev_hold(indev); + if (outdev) dev_hold(outdev); + ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ if (skb->nf_bridge) { ++ physindev = skb->nf_bridge->physindev; ++ if (physindev) dev_hold(physindev); ++ physoutdev = skb->nf_bridge->physoutdev; ++ if (physoutdev) dev_hold(physoutdev); ++ } ++#endif ++ + status = queue_handler[pf].outfn(skb, info, queue_handler[pf].data); + if (status < 0) { + /* James M doesn't say fuck enough. */ + if (indev) dev_put(indev); + if (outdev) dev_put(outdev); ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ if (physindev) dev_put(physindev); ++ if (physoutdev) dev_put(physoutdev); ++#endif + kfree(info); + kfree_skb(skb); + return; +@@ -451,7 +473,8 @@ + int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb, + struct net_device *indev, + struct net_device *outdev, +- int (*okfn)(struct sk_buff *)) ++ int (*okfn)(struct sk_buff *), ++ int hook_thresh) + { + struct list_head *elem; + unsigned int verdict; +@@ -483,7 +506,7 @@ + + elem = &nf_hooks[pf][hook]; + verdict = nf_iterate(&nf_hooks[pf][hook], &skb, hook, indev, +- outdev, &elem, okfn); ++ outdev, &elem, okfn, hook_thresh); + if (verdict == NF_QUEUE) { + NFDEBUG("nf_hook: Verdict = QUEUE.\n"); + nf_queue(skb, elem, pf, hook, indev, outdev, okfn); +@@ -512,6 +535,14 @@ + + /* We don't have BR_NETPROTO_LOCK here */ + br_read_lock_bh(BR_NETPROTO_LOCK); ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ if (skb->nf_bridge) { ++ if (skb->nf_bridge->physindev) ++ dev_put(skb->nf_bridge->physindev); ++ if (skb->nf_bridge->physoutdev) ++ dev_put(skb->nf_bridge->physoutdev); ++ } ++#endif + for (i = nf_hooks[info->pf][info->hook].next; i != elem; i = i->next) { + if (i == &nf_hooks[info->pf][info->hook]) { + /* The module which sent it to userspace is gone. */ +@@ -532,7 +563,7 @@ + verdict = nf_iterate(&nf_hooks[info->pf][info->hook], + &skb, info->hook, + info->indev, info->outdev, &elem, +- info->okfn); ++ info->okfn, INT_MIN); + } + + switch (verdict) { +diff -Nurb src/linux/linux.stock/net/core/skbuff.c src/linux/linux/net/core/skbuff.c +--- src/linux/linux.stock/net/core/skbuff.c 2003-10-14 04:09:32.000000000 -0400 ++++ src/linux/linux/net/core/skbuff.c 2004-07-10 23:46:39.000000000 -0400 +@@ -244,6 +244,9 @@ + #ifdef CONFIG_NETFILTER_DEBUG + skb->nf_debug = 0; + #endif ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ skb->nf_bridge = NULL; ++#endif + #endif + #ifdef CONFIG_NET_SCHED + skb->tc_index = 0; +@@ -324,6 +327,9 @@ + } + #ifdef CONFIG_NETFILTER + nf_conntrack_put(skb->nfct); ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ nf_bridge_put(skb->nf_bridge); ++#endif + #endif + skb_headerinit(skb, NULL, 0); /* clean state */ + kfree_skbmem(skb); +@@ -390,6 +396,9 @@ + #ifdef CONFIG_NETFILTER_DEBUG + C(nf_debug); + #endif ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ C(nf_bridge); ++#endif + #endif /*CONFIG_NETFILTER*/ + #if defined(CONFIG_HIPPI) + C(private); +@@ -402,6 +411,9 @@ + skb->cloned = 1; + #ifdef CONFIG_NETFILTER + nf_conntrack_get(skb->nfct); ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ nf_bridge_get(skb->nf_bridge); ++#endif + #endif + return n; + } +@@ -436,6 +448,10 @@ + #ifdef CONFIG_NETFILTER_DEBUG + new->nf_debug=old->nf_debug; + #endif ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ new->nf_bridge=old->nf_bridge; ++ nf_bridge_get(new->nf_bridge); ++#endif + #endif + #ifdef CONFIG_NET_SCHED + new->tc_index = old->tc_index; +@@ -722,8 +738,8 @@ + /* Set the tail pointer and length */ + skb_put(n,skb->len); + +- /* Copy the data only. */ +- if (skb_copy_bits(skb, 0, n->data, skb->len)) ++ /* Copy the linear data and header. */ ++ if (skb_copy_bits(skb, -newheadroom, n->head, newheadroom + skb->len)) + BUG(); + + copy_skb_header(n, skb); +diff -Nurb src/linux/linux.stock/net/ipv4/ip_output.c src/linux/linux/net/ipv4/ip_output.c +--- src/linux/linux.stock/net/ipv4/ip_output.c 2003-10-14 04:09:33.000000000 -0400 ++++ src/linux/linux/net/ipv4/ip_output.c 2004-07-10 23:46:39.000000000 -0400 +@@ -879,6 +879,10 @@ + /* Connection association is same as pre-frag packet */ + skb2->nfct = skb->nfct; + nf_conntrack_get(skb2->nfct); ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ skb2->nf_bridge = skb->nf_bridge; ++ nf_bridge_get(skb2->nf_bridge); ++#endif + #ifdef CONFIG_NETFILTER_DEBUG + skb2->nf_debug = skb->nf_debug; + #endif +diff -Nurb src/linux/linux.stock/net/ipv4/netfilter/Config.in src/linux/linux/net/ipv4/netfilter/Config.in +--- src/linux/linux.stock/net/ipv4/netfilter/Config.in 2004-07-10 23:30:19.000000000 -0400 ++++ src/linux/linux/net/ipv4/netfilter/Config.in 2004-07-10 23:46:39.000000000 -0400 +@@ -83,6 +83,9 @@ + dep_tristate ' String match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_STRING $CONFIG_IP_NF_IPTABLES + dep_tristate ' Owner match support (EXPERIMENTAL)' CONFIG_IP_NF_MATCH_OWNER $CONFIG_IP_NF_IPTABLES + fi ++ if [ "$CONFIG_BRIDGE" != "n" ]; then ++ dep_tristate ' Physdev match support' CONFIG_IP_NF_MATCH_PHYSDEV $CONFIG_IP_NF_IPTABLES ++ fi + # The targets + dep_tristate ' Packet filtering' CONFIG_IP_NF_FILTER $CONFIG_IP_NF_IPTABLES + if [ "$CONFIG_IP_NF_FILTER" != "n" ]; then +diff -Nurb src/linux/linux.stock/net/ipv4/netfilter/Makefile src/linux/linux/net/ipv4/netfilter/Makefile +--- src/linux/linux.stock/net/ipv4/netfilter/Makefile 2004-07-10 23:30:19.000000000 -0400 ++++ src/linux/linux/net/ipv4/netfilter/Makefile 2004-07-10 23:46:39.000000000 -0400 +@@ -149,6 +149,8 @@ + obj-$(CONFIG_IP_NF_MATCH_TCPMSS) += ipt_tcpmss.o + obj-$(CONFIG_IP_NF_MATCH_REALM) += ipt_realm.o + ++obj-$(CONFIG_IP_NF_MATCH_PHYSDEV) += ipt_physdev.o ++ + # targets + obj-$(CONFIG_IP_NF_TARGET_REJECT) += ipt_REJECT.o + obj-$(CONFIG_IP_NF_TARGET_MIRROR) += ipt_MIRROR.o +diff -Nurb src/linux/linux.stock/net/ipv4/netfilter/ip_tables.c src/linux/linux/net/ipv4/netfilter/ip_tables.c +--- src/linux/linux.stock/net/ipv4/netfilter/ip_tables.c 2004-07-10 23:29:53.000000000 -0400 ++++ src/linux/linux/net/ipv4/netfilter/ip_tables.c 2004-07-10 23:46:39.000000000 -0400 +@@ -121,12 +121,19 @@ + static inline int + ip_packet_match(const struct iphdr *ip, + const char *indev, ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ const char *physindev, ++#endif + const char *outdev, ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ const char *physoutdev, ++#endif + const struct ipt_ip *ipinfo, + int isfrag) + { + size_t i; + unsigned long ret; ++ unsigned long ret2 = 1; + + #define FWINV(bool,invflg) ((bool) ^ !!(ipinfo->invflags & invflg)) + +@@ -156,7 +163,15 @@ + & ((const unsigned long *)ipinfo->iniface_mask)[i]; + } + +- if (FWINV(ret != 0, IPT_INV_VIA_IN)) { ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ for (i = 0, ret2 = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { ++ ret2 |= (((const unsigned long *)physindev)[i] ++ ^ ((const unsigned long *)ipinfo->iniface)[i]) ++ & ((const unsigned long *)ipinfo->iniface_mask)[i]; ++ } ++#endif ++ ++ if (FWINV(ret != 0 && ret2 != 0, IPT_INV_VIA_IN)) { + dprintf("VIA in mismatch (%s vs %s).%s\n", + indev, ipinfo->iniface, + ipinfo->invflags&IPT_INV_VIA_IN ?" (INV)":""); +@@ -169,7 +184,15 @@ + & ((const unsigned long *)ipinfo->outiface_mask)[i]; + } + +- if (FWINV(ret != 0, IPT_INV_VIA_OUT)) { ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ for (i = 0, ret2 = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { ++ ret2 |= (((const unsigned long *)physoutdev)[i] ++ ^ ((const unsigned long *)ipinfo->outiface)[i]) ++ & ((const unsigned long *)ipinfo->outiface_mask)[i]; ++ } ++#endif ++ ++ if (FWINV(ret != 0 && ret2 != 0, IPT_INV_VIA_OUT)) { + dprintf("VIA out mismatch (%s vs %s).%s\n", + outdev, ipinfo->outiface, + ipinfo->invflags&IPT_INV_VIA_OUT ?" (INV)":""); +@@ -272,6 +295,9 @@ + /* Initializing verdict to NF_DROP keeps gcc happy. */ + unsigned int verdict = NF_DROP; + const char *indev, *outdev; ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ const char *physindev, *physoutdev; ++#endif + void *table_base; + struct ipt_entry *e, *back; + +@@ -281,6 +307,13 @@ + datalen = (*pskb)->len - ip->ihl * 4; + indev = in ? in->name : nulldevname; + outdev = out ? out->name : nulldevname; ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ physindev = ((*pskb)->nf_bridge && (*pskb)->nf_bridge->physindev) ? ++ (*pskb)->nf_bridge->physindev->name : nulldevname; ++ physoutdev = ((*pskb)->nf_bridge && (*pskb)->nf_bridge->physoutdev) ? ++ (*pskb)->nf_bridge->physoutdev->name : nulldevname; ++#endif ++ + /* We handle fragments by dealing with the first fragment as + * if it was a normal packet. All other fragments are treated + * normally, except that they will NEVER match rules that ask +@@ -316,7 +349,15 @@ + IP_NF_ASSERT(e); + IP_NF_ASSERT(back); + (*pskb)->nfcache |= e->nfcache; +- if (ip_packet_match(ip, indev, outdev, &e->ip, offset)) { ++ if (ip_packet_match(ip, indev, ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ physindev, ++#endif ++ outdev, ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ physoutdev, ++#endif ++ &e->ip, offset)) { + struct ipt_entry_target *t; + + if (IPT_MATCH_ITERATE(e, do_match, +diff -Nurb src/linux/linux.stock/net/ipv4/netfilter/ipt_LOG.c src/linux/linux/net/ipv4/netfilter/ipt_LOG.c +--- src/linux/linux.stock/net/ipv4/netfilter/ipt_LOG.c 2004-07-10 23:29:56.000000000 -0400 ++++ src/linux/linux/net/ipv4/netfilter/ipt_LOG.c 2004-07-10 23:46:39.000000000 -0400 +@@ -319,6 +319,18 @@ + prefix == NULL ? loginfo->prefix : prefix, + in ? in->name : "", + out ? out->name : ""); ++#if defined(CONFIG_BRIDGE) || defined(CONFIG_BRIDGE_MODULE) ++ if ((*pskb)->nf_bridge) { ++ struct net_device *physindev = (*pskb)->nf_bridge->physindev; ++ struct net_device *physoutdev = (*pskb)->nf_bridge->physoutdev; ++ ++ if (physindev && in != physindev) ++ printk("PHYSIN=%s ", physindev->name); ++ if (physoutdev && out != physoutdev) ++ printk("PHYSOUT=%s ", physoutdev->name); ++ } ++#endif ++ + if (in && !out) { + /* MAC logging for input chain only. */ + printk("MAC="); +diff -Nurb src/linux/linux.stock/net/ipv4/netfilter/ipt_physdev.c src/linux/linux/net/ipv4/netfilter/ipt_physdev.c +--- src/linux/linux.stock/net/ipv4/netfilter/ipt_physdev.c 1969-12-31 19:00:00.000000000 -0500 ++++ src/linux/linux/net/ipv4/netfilter/ipt_physdev.c 2004-07-10 23:46:39.000000000 -0400 +@@ -0,0 +1,127 @@ ++/* Kernel module to match the bridge port in and ++ * out device for IP packets coming into contact with a bridge. */ ++#include ++#include ++#include ++#include ++#include ++#include ++#define MATCH 1 ++#define NOMATCH 0 ++ ++static int ++match(const struct sk_buff *skb, ++ const struct net_device *in, ++ const struct net_device *out, ++ const void *matchinfo, ++ int offset, ++ const void *hdr, ++ u_int16_t datalen, ++ int *hotdrop) ++{ ++ int i; ++ static const char nulldevname[IFNAMSIZ] = { 0 }; ++ const struct ipt_physdev_info *info = matchinfo; ++ unsigned long ret; ++ const char *indev, *outdev; ++ struct nf_bridge_info *nf_bridge; ++ ++ /* Not a bridged IP packet or no info available yet: ++ * LOCAL_OUT/mangle and LOCAL_OUT/nat don't know if ++ * the destination device will be a bridge. */ ++ if (!(nf_bridge = skb->nf_bridge)) { ++ /* Return MATCH if the invert flags of the used options are on */ ++ if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && ++ !(info->invert & IPT_PHYSDEV_OP_BRIDGED)) ++ return NOMATCH; ++ if ((info->bitmask & IPT_PHYSDEV_OP_ISIN) && ++ !(info->invert & IPT_PHYSDEV_OP_ISIN)) ++ return NOMATCH; ++ if ((info->bitmask & IPT_PHYSDEV_OP_ISOUT) && ++ !(info->invert & IPT_PHYSDEV_OP_ISOUT)) ++ return NOMATCH; ++ if ((info->bitmask & IPT_PHYSDEV_OP_IN) && ++ !(info->invert & IPT_PHYSDEV_OP_IN)) ++ return NOMATCH; ++ if ((info->bitmask & IPT_PHYSDEV_OP_OUT) && ++ !(info->invert & IPT_PHYSDEV_OP_OUT)) ++ return NOMATCH; ++ return MATCH; ++ } ++ ++ /* This only makes sense in the FORWARD and POSTROUTING chains */ ++ if ((info->bitmask & IPT_PHYSDEV_OP_BRIDGED) && ++ (!!(nf_bridge->mask & BRNF_BRIDGED) ^ ++ !(info->invert & IPT_PHYSDEV_OP_BRIDGED))) ++ return NOMATCH; ++ ++ if ((info->bitmask & IPT_PHYSDEV_OP_ISIN && ++ (!nf_bridge->physindev ^ !!(info->invert & IPT_PHYSDEV_OP_ISIN))) || ++ (info->bitmask & IPT_PHYSDEV_OP_ISOUT && ++ (!nf_bridge->physoutdev ^ !!(info->invert & IPT_PHYSDEV_OP_ISOUT)))) ++ return NOMATCH; ++ ++ if (!(info->bitmask & IPT_PHYSDEV_OP_IN)) ++ goto match_outdev; ++ indev = nf_bridge->physindev ? nf_bridge->physindev->name : nulldevname; ++ for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { ++ ret |= (((const unsigned long *)indev)[i] ++ ^ ((const unsigned long *)info->physindev)[i]) ++ & ((const unsigned long *)info->in_mask)[i]; ++ } ++ ++ if ((ret == 0) ^ !(info->invert & IPT_PHYSDEV_OP_IN)) ++ return NOMATCH; ++ ++match_outdev: ++ if (!(info->bitmask & IPT_PHYSDEV_OP_OUT)) ++ return MATCH; ++ outdev = nf_bridge->physoutdev ? ++ nf_bridge->physoutdev->name : nulldevname; ++ for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) { ++ ret |= (((const unsigned long *)outdev)[i] ++ ^ ((const unsigned long *)info->physoutdev)[i]) ++ & ((const unsigned long *)info->out_mask)[i]; ++ } ++ ++ return (ret != 0) ^ !(info->invert & IPT_PHYSDEV_OP_OUT); ++} ++ ++static int ++checkentry(const char *tablename, ++ const struct ipt_ip *ip, ++ void *matchinfo, ++ unsigned int matchsize, ++ unsigned int hook_mask) ++{ ++ const struct ipt_physdev_info *info = matchinfo; ++ ++ if (matchsize != IPT_ALIGN(sizeof(struct ipt_physdev_info))) ++ return 0; ++ if (!(info->bitmask & IPT_PHYSDEV_OP_MASK) || ++ info->bitmask & ~IPT_PHYSDEV_OP_MASK) ++ return 0; ++ return 1; ++} ++ ++static struct ipt_match physdev_match = { ++ .name = "physdev", ++ .match = &match, ++ .checkentry = &checkentry, ++ .me = THIS_MODULE, ++}; ++ ++static int __init init(void) ++{ ++ return ipt_register_match(&physdev_match); ++} ++ ++static void __exit fini(void) ++{ ++ ipt_unregister_match(&physdev_match); ++} ++ ++module_init(init); ++module_exit(fini); ++MODULE_LICENSE("GPL"); ++EXPORT_NO_SYMBOLS; diff --git a/obsolete-buildroot/sources/openwrt/patches/wrt54g-router.patch b/obsolete-buildroot/sources/openwrt/patches/wrt54g-router.patch new file mode 100644 index 0000000000..4098f792e2 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/patches/wrt54g-router.patch @@ -0,0 +1,240 @@ +diff -bBurN WRT54G/release/src/router/rc/Makefile-openwrt WRT54G.new/release/src/router/rc/Makefile-openwrt +--- WRT54G/release/src/router/rc/Makefile-openwrt 1969-12-31 18:00:00.000000000 -0600 ++++ WRT54G.new/release/src/router/rc/Makefile-openwrt 2004-03-03 16:23:40.000000000 -0600 +@@ -0,0 +1,44 @@ ++# Copyright 2001-2003, Broadcom Corporation ++# All Rights Reserved. ++# ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE ++# ++ ++# ++# Router Wireless Interface Configuration Utility Makefile ++# ++# Copyright 2003, Broadcom Corporation ++# All Rights Reserved. ++# ++# ++# $Id: Makefile,v 1.2 2004/01/13 00:55:58 mbm Exp $ ++# ++ ++CFLAGS += -I. -I$(TOP)/shared -I$(SRCBASE)/include -Wall ++#CFLAGS += -g -DDEBUG ++CFLAGS += -s -Os ++LDFLAGS += -L$(TOP)/shared -lshared -L$(TOP)/nvram -lnvram ++ ++OBJS := mtd.o crc.o #http.o ++ ++vpath %.c $(TOP)/shared $(SRCBASE)/rts/src ++ ++all: mtd ++ ++clean: ++ rm -f *.o mtd ++ ++install: all ++ install -d $(INSTALLDIR)/sbin ++ install mtd $(INSTALLDIR)/sbin ++ $(STRIP) $(INSTALLDIR)/sbin/mtd ++ ++mtd.o: mtd.c ++ $(CC) -c $^ $(CFLAGS) $(CPPFLAGS) -DOPENWRT_MTD #-DOPENWRT_MTD_HTTP_GET ++ ++mtd: $(OBJS) ++ $(CC) -o $@ $^ $(LDFLAGS) +diff -bBurN WRT54G/release/src/router/rc/mtd.c WRT54G.new/release/src/router/rc/mtd.c +--- WRT54G/release/src/router/rc/mtd.c 2004-01-19 20:34:50.000000000 -0600 ++++ WRT54G.new/release/src/router/rc/mtd.c 2004-03-03 16:24:42.000000000 -0600 +@@ -37,6 +37,86 @@ + #include + #include + ++ ++#ifdef OPENWRT_MTD ++ ++extern int ++mtd_open(const char *mtd, int flags); ++extern int ++mtd_erase(const char *mtd); ++extern int ++mtd_write(const char *path, const char *mtd); ++ ++/* Slightly modified version of mtd_erase. */ ++int ++mtd_unlock(const char *mtd) ++{ ++ int mtd_fd; ++ mtd_info_t mtd_info; ++ erase_info_t erase_info; ++ ++ /* Open MTD device */ ++ if ((mtd_fd = mtd_open(mtd, O_RDWR)) < 0) { ++ perror(mtd); ++ return errno; ++ } ++ ++ /* Get sector size */ ++ if (ioctl(mtd_fd, MEMGETINFO, &mtd_info) != 0) { ++ perror(mtd); ++ close(mtd_fd); ++ return errno; ++ } ++ ++ erase_info.length = mtd_info.erasesize; ++ ++ for (erase_info.start = 0; ++ erase_info.start < mtd_info.size; ++ erase_info.start += mtd_info.erasesize) { ++ (void) ioctl(mtd_fd, MEMUNLOCK, &erase_info); ++/* if (ioctl(mtd_fd, MEMERASE, &erase_info) != 0) { */ ++/* perror(mtd); */ ++/* close(mtd_fd); */ ++/* return errno; */ ++/* } */ ++ } ++ ++ close(mtd_fd); ++ return 0; ++} ++ ++int main(int argc, char **argv) { ++ if(argc == 3 && strcasecmp(argv[1],"unlock")==0) { ++ printf("Unlocking %s\n",argv[2]); ++ return mtd_unlock(argv[2]); ++ } ++ if(argc == 3 && strcasecmp(argv[1],"erase")==0) { ++ printf("Erasing %s\n",argv[2]); ++ return mtd_erase(argv[2]); ++ } ++ if(argc == 4 && strcasecmp(argv[1],"write")==0) { ++ printf("writing %s to %s\n",argv[2],argv[3]); ++ return mtd_write(argv[2],argv[3]); ++ } ++ ++ printf("no valid command given\n"); ++ return -1; ++} ++ ++#ifndef OPENWRT_MTD_HTTP_GET ++/* Dummy routines when no http support. */ ++int ++http_get(const char *server, char *buf, size_t count, off_t offset) ++{ ++ printf("error opening %s\n",server); ++ exit(-1); ++} ++#endif ++ ++#define check_action() (fp ? ACT_IDLE : ACT_WEBS_UPGRADE) ++ ++#endif ++ + /* + * Open an MTD device + * @param mtd path to or partition name of MTD device +diff -bBurN WRT54G/release/src/router/shared/Makefile-openwrt WRT54G.new/release/src/router/shared/Makefile-openwrt +--- WRT54G/release/src/router/shared/Makefile-openwrt 1969-12-31 18:00:00.000000000 -0600 ++++ WRT54G.new/release/src/router/shared/Makefile-openwrt 2004-03-03 12:39:17.000000000 -0600 +@@ -0,0 +1,41 @@ ++# ++# Linux router shared code Makefile ++# ++# Copyright 2001-2003, Broadcom Corporation ++# All Rights Reserved. ++# ++# THIS SOFTWARE IS OFFERED "AS IS", AND BROADCOM GRANTS NO WARRANTIES OF ANY ++# KIND, EXPRESS OR IMPLIED, BY STATUTE, COMMUNICATION OR OTHERWISE. BROADCOM ++# SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS ++# FOR A SPECIFIC PURPOSE OR NONINFRINGEMENT CONCERNING THIS SOFTWARE. ++# ++# $Id: Makefile,v 1.3 2004/01/13 00:51:09 mbm Exp $ ++# ++ifneq ($(wildcard $(SRCBASE)/cy_conf.mak),) ++ include $(SRCBASE)/cy_conf.mak ++endif ++ ++CFLAGS += -I. -I$(SRCBASE)/include -Wall -I$(SRCBASE)/ ++#CFLAGS += -g -DDEBUG ++CFLAGS += -s -Os ++LDFLAGS += -L. ++ ++all: libshared.so ++ ++install: all ++ install -d $(INSTALLDIR)/usr/lib ++ install -m 755 libshared.so $(INSTALLDIR)/usr/lib ++ $(STRIP) $(INSTALLDIR)/usr/lib/libshared.so ++ ++clean: ++ rm -f *.o *.so ++ ++libshared.so: shutils.o wl.o wl_linux.o defaults.o ++ $(LD) -shared -o $@ $^ ++ ++build_date.o: build_date.c ++ ++build_date: ++ echo "const char *builddate = \"`date`\";" > build_date.c ++ ++*.o: $(CY_DEPS) +diff -bBurN WRT54GS/release/src/router/nvram/nvram_linux.c-dist WRT54GS.new/release/src/router/nvram/nvram_linux.c +--- WRT54GS/release/src/router/nvram/nvram_linux.c-dist 2004-03-30 10:04:10.000000000 -0600 ++++ WRT54GS/release/src/router/nvram/nvram_linux.c 2004-03-30 10:10:09.000000000 -0600 +@@ -27,8 +27,10 @@ + #include + #include + #include ++#ifndef OPENWRT_NVRAM + #include + #include ++#endif + + #define PATH_DEV_NVRAM "/dev/nvram" + +@@ -182,6 +184,20 @@ + { + int ret; + ++#ifdef OPENWRT_NVRAM ++ fprintf(stderr, "nvram_commit(): start\n"); ++ ++ if (nvram_fd < 0) ++ if ((ret = nvram_init(NULL))) ++ return ret; ++ ++ ret = ioctl(nvram_fd, NVRAM_MAGIC, NULL); ++ ++ if (ret < 0) ++ perror(PATH_DEV_NVRAM); ++ ++ fprintf(stderr, "nvram_commit(): end\n"); ++#else + cprintf("nvram_commit(): start\n"); + + if((check_action() == ACT_IDLE) || +@@ -200,6 +216,7 @@ + } + else + cprintf("nvram_commit(): nothing to do...\n"); ++#endif + + return ret; + } +@@ -272,6 +289,7 @@ + return j; + } + ++#ifndef OPENWRT_NVRAM + int + check_action(void) + { +@@ -318,3 +336,5 @@ + + return 0; + } ++ ++#endif diff --git a/obsolete-buildroot/sources/openwrt/patches/wrt54g-shared.patch b/obsolete-buildroot/sources/openwrt/patches/wrt54g-shared.patch new file mode 100644 index 0000000000..f357885bcc --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/patches/wrt54g-shared.patch @@ -0,0 +1,11 @@ +--- WRT54G/release/src/shared/sbpci.c-dist 2004-03-15 13:13:37.000000000 -0600 ++++ WRT54G/release/src/shared/sbpci.c 2004-03-15 13:15:38.000000000 -0600 +@@ -269,7 +269,7 @@ + sb_core_reset(sbh, 0); + + /* In some board, */ +- if(nvram_match("boardtype", "bcm94710dev")) ++ if(nvram_match("boardtype", "bcm94710dev") || nvram_match("boardtype", "bcm94710ap")) + CT4712_WR = 0; + else + CT4712_WR = 1; diff --git a/obsolete-buildroot/sources/openwrt/tools/addpattern.c b/obsolete-buildroot/sources/openwrt/tools/addpattern.c new file mode 100644 index 0000000000..dbf8ed690e --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/tools/addpattern.c @@ -0,0 +1,202 @@ +/* + * Copyright (C) 2004 Manuel Novoa III + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* July 29, 2004 + * + * This is a hacked replacement for the 'addpattern' utility used to + * create wrt54g .bin firmware files. It isn't pretty, but it does + * the job for me. + * + * Extensions: + * -v allows setting the version string on the command line. + * -{0|1} sets the (currently ignored) hw_ver flag in the header + * to 0 or 1 respectively. + */ + +#include +#include +#include +#include +#include +#include + +/**********************************************************************/ + +#define CODE_ID "U2ND" /* from code_pattern.h */ +#define CODE_PATTERN "W54S" /* from code_pattern.h */ + +#define CYBERTAN_VERSION "v2.07.1" /* from cyutils.h */ +/* #define CYBERTAN_VERSION "v2.04.3" */ + +struct code_header { /* from cyutils.h */ + char magic[4]; + char res1[4]; /* for extra magic */ + char fwdate[3]; + char fwvern[3]; + char id[4]; /* U2ND */ +#if 0 + unsigned char res2[14]; +#else + char hw_ver; /* 0: for 4702, 1: for 4712 -- new in 2.04.3 */ + unsigned char res2[13]; +#endif +} ; + +/**********************************************************************/ + +void usage(void) __attribute__ (( __noreturn__ )); + +void usage(void) +{ + fprintf(stderr, "Usage: addpattern [-i trxfile] [-o binfile] [-p pattern] [-g] [-v v#.#.#] [-{0|1}]\n"); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + char buf[1024]; /* keep this at 1k or adjust garbage calc below */ + struct code_header *hdr; + FILE *in = stdin; + FILE *out = stdout; + char *ifn = NULL; + char *ofn = NULL; + char *pattern = CODE_PATTERN; + char *version = CYBERTAN_VERSION; + int gflag = 0; + int c; + int v0, v1, v2; + size_t off, n; + time_t t; + struct tm *ptm; + + fprintf(stderr, "mjn3's addpattern replacement - v0.80\n"); + + hdr = (struct code_header *) buf; + + while ((c = getopt(argc, argv, "i:o:p:gv:01")) != -1) { + switch (c) { + case 'i': + ifn = optarg; + break; + case 'o': + ofn = optarg; + break; + case 'p': + pattern = optarg; + break; + case 'g': + gflag = 1; + break; + case 'v': /* extension to allow setting version */ + version = optarg; + break; + case '0': + hdr->hw_ver = 0; + break; + case '1': + hdr->hw_ver = 1; + break; + default: + usage(); + } + } + + if (optind != argc) { + fprintf(stderr, "illegal arg \"%s\"\n", argv[optind]); + usage(); + } + + if (strlen(pattern) != 4) { + fprintf(stderr, "illegal pattern \"%s\": length != 4\n", pattern); + usage(); + } + + if (ifn && !(in = fopen(ifn, "r"))) { + fprintf(stderr, "can not open \"%s\" for reading\n", ifn); + usage(); + } + + if (ofn && !(out = fopen(ofn, "w"))) { + fprintf(stderr, "can not open \"%s\" for writing\n", ofn); + usage(); + } + + if (time(&t) == (time_t)(-1)) { + fprintf(stderr, "time call failed\n"); + return EXIT_FAILURE; + } + + ptm = localtime(&t); + + if (3 != sscanf(version, "v%d.%d.%d", &v0, &v1, &v2)) { + fprintf(stderr, "bad version string \"%s\"\n", version); + return EXIT_FAILURE; + } + + memset(hdr, 0, sizeof(struct code_header)); + memcpy(&hdr->magic, pattern, 4); + hdr->fwdate[0] = ptm->tm_year % 100; + hdr->fwdate[1] = ptm->tm_mon + 1; + hdr->fwdate[2] = ptm->tm_mday; + hdr->fwvern[0] = v0; + hdr->fwvern[1] = v1; + hdr->fwvern[2] = v2; + memcpy(&hdr->id, CODE_ID, strlen(CODE_ID)); + + off = sizeof(struct code_header); + + fprintf(stderr, "writing firmware v%d.%d.%d on %d/%d/%d (y/m/d)\n", + v0, v1, v2, + hdr->fwdate[0], hdr->fwdate[1], hdr->fwdate[2]); + + + while ((n = fread(buf + off, 1, sizeof(buf)-off, in) + off) > 0) { + off = 0; + if (n < sizeof(buf)) { + if (ferror(in)) { + FREAD_ERROR: + fprintf(stderr, "fread error\n"); + return EXIT_FAILURE; + } + if (gflag) { + gflag = sizeof(buf) - n; + memset(buf + n, 0xff, gflag); + fprintf(stderr, "adding %d bytes of garbage\n", gflag); + n = sizeof(buf); + } + } + if (!fwrite(buf, n, 1, out)) { + FWRITE_ERROR: + fprintf(stderr, "fwrite error\n"); + return EXIT_FAILURE; + } + } + + if (ferror(in)) { + goto FREAD_ERROR; + } + + if (fflush(out)) { + goto FWRITE_ERROR; + } + + fclose(in); + fclose(out); + + return EXIT_SUCCESS; +} diff --git a/obsolete-buildroot/sources/openwrt/tools/trx.c b/obsolete-buildroot/sources/openwrt/tools/trx.c new file mode 100644 index 0000000000..5ec53fdcb3 --- /dev/null +++ b/obsolete-buildroot/sources/openwrt/tools/trx.c @@ -0,0 +1,316 @@ +/* + * Copyright (C) 2004 Manuel Novoa III + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* July 29, 2004 + * + * This is a hacked replacement for the 'trx' utility used to create + * wrt54g .trx firmware files. It isn't pretty, but it does the job + * for me. + * + * As an extension, you can specify a larger maximum length for the + * .trx file using '-m'. It will be rounded up to be a multiple of 4K. + * NOTE: This space will be malloc()'d. + * + * TODO: Support '-b' option to specify offsets for each file. + */ + +#include +#include +#include +#include +#include +#include +#include + +uint32_t crc32buf(char *buf, size_t len); + +/**********************************************************************/ +/* from trxhdr.h */ + +#define TRX_MAGIC 0x30524448 /* "HDR0" */ +#define TRX_VERSION 1 +#define TRX_MAX_LEN 0x3A0000 +#define TRX_NO_HEADER 1 /* Do not write TRX header */ + +struct trx_header { + uint32_t magic; /* "HDR0" */ + uint32_t len; /* Length of file including header */ + uint32_t crc32; /* 32-bit CRC from flag_version to end of file */ + uint32_t flag_version; /* 0:15 flags, 16:31 version */ + uint32_t offsets[3]; /* Offsets of partitions from start of header */ +}; + +/**********************************************************************/ + +void usage(void) __attribute__ (( __noreturn__ )); + +void usage(void) +{ + fprintf(stderr, "Usage: trx [-o outfile] [-m maxlen] file [file [file]]\n"); + exit(EXIT_FAILURE); +} + +int main(int argc, char **argv) +{ + FILE *out = stdout; + FILE *in; + char *ofn = NULL; + char *buf; + char *e; + int c, i; + size_t n; + unsigned long maxlen = TRX_MAX_LEN; + struct trx_header *p; + + fprintf(stderr, "mjn3's trx replacement - v0.80\n"); + + while ((c = getopt(argc, argv, "o:m:")) != -1) { + switch (c) { + case 'o': + ofn = optarg; + break; + case 'm': + errno = 0; + maxlen = strtoul(optarg, &e, 0); + if (errno || (e == optarg) || *e) { + fprintf(stderr, "illegal numeric string\n"); + usage(); + } +#undef ROUND +#define ROUND 0x1000 + if (maxlen & (ROUND-1)) { + maxlen += (ROUND - (maxlen & (ROUND-1))); + } + if (maxlen < ROUND) { + fprintf(stderr, "maxlen too small (or wrapped)\n"); + usage(); + } + break; + default: + usage(); + } + } + + if (ofn && !(out = fopen(ofn, "w"))) { + fprintf(stderr, "can not open \"%s\" for writing\n", ofn); + usage(); + } + + if (optind == argc) { + fprintf(stderr, "we require at least one arg\n"); + usage(); + } + + if (argc - optind > 3) { + fprintf(stderr, "too many args: %d > 3\n", argc - optind); + usage(); + } + + if (maxlen > TRX_MAX_LEN) { + fprintf(stderr, "WARNING: maxlen exceeds default maximum! Beware of overwriting nvram!\n"); + } + + if (!(buf = malloc(maxlen))) { + fprintf(stderr, "malloc failed\n"); + return EXIT_FAILURE; + } + + p = (struct trx_header *) buf; + + p->magic = TRX_MAGIC; + p->len = sizeof(struct trx_header); + p->flag_version = (TRX_VERSION << 16); + + i = 0; + + while (optind < argc) { + p->offsets[i++] = p->len; + + if (!(in = fopen(argv[optind], "r"))) { + fprintf(stderr, "can not open \"%s\" for reading\n", argv[optind]); + usage(); + } + + n = fread(buf + p->len, 1, maxlen - p->len, in); + if (!feof(in)) { + fprintf(stderr, "fread failure or file \"%s\" too large\n", + argv[optind]); + fclose(in); + return EXIT_FAILURE; + } + + fclose(in); + + ++optind; + + if (optind < argc) { +#undef ROUND +#define ROUND 4 + if (n & (ROUND-1)) { + memset(buf + p->len + n, 0, ROUND - (n & (ROUND-1))); + n += ROUND - (n & (ROUND-1)); + } + } + + p->len += n; + } + +#undef ROUND +#define ROUND 0x1000 + n = p->len & (ROUND-1); + if (n) { + memset(buf + p->len, 0, ROUND - n); + p->len += ROUND - n; + } + + p->crc32 = crc32buf((char *) &p->flag_version, + p->len - offsetof(struct trx_header, flag_version)); + + if (!fwrite(buf, p->len, 1, out) || fflush(out)) { + fprintf(stderr, "fwrite failed\n"); + return EXIT_FAILURE; + } + + fclose(out); + + return EXIT_SUCCESS; +} + +/**********************************************************************/ +/* The following was grabbed and tweaked from the old snippets collection + * of public domain C code. */ + +/**********************************************************************\ +|* Demonstration program to compute the 32-bit CRC used as the frame *| +|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *| +|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *| +|* protocol). The 32-bit FCS was added via the Federal Register, *| +|* 1 June 1982, p.23798. I presume but don't know for certain that *| +|* this polynomial is or will be included in CCITT V.41, which *| +|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *| +|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *| +|* errors by a factor of 10^-5 over 16-bit FCS. *| +\**********************************************************************/ + +/* Copyright (C) 1986 Gary S. Brown. You may use this program, or + code or tables extracted from it, as desired without restriction.*/ + +/* First, the polynomial itself and its table of feedback terms. The */ +/* polynomial is */ +/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ +/* Note that we take it "backwards" and put the highest-order term in */ +/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */ +/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */ +/* the MSB being 1. */ + +/* Note that the usual hardware shift register implementation, which */ +/* is what we're using (we're merely optimizing it by doing eight-bit */ +/* chunks at a time) shifts bits into the lowest-order term. In our */ +/* implementation, that means shifting towards the right. Why do we */ +/* do it this way? Because the calculated CRC must be transmitted in */ +/* order from highest-order term to lowest-order term. UARTs transmit */ +/* characters in order from LSB to MSB. By storing the CRC this way, */ +/* we hand it to the UART in the order low-byte to high-byte; the UART */ +/* sends each low-bit to hight-bit; and the result is transmission bit */ +/* by bit from highest- to lowest-order term without requiring any bit */ +/* shuffling on our part. Reception works similarly. */ + +/* The feedback terms table consists of 256, 32-bit entries. Notes: */ +/* */ +/* 1. The table can be generated at runtime if desired; code to do so */ +/* is shown later. It might not be obvious, but the feedback */ +/* terms simply represent the results of eight shift/xor opera- */ +/* tions for all combinations of data and CRC register values. */ +/* */ +/* 2. The CRC accumulation logic is the same for all CRC polynomials, */ +/* be they sixteen or thirty-two bits wide. You simply choose the */ +/* appropriate table. Alternatively, because the table can be */ +/* generated at runtime, you can start by generating the table for */ +/* the polynomial in question and use exactly the same "updcrc", */ +/* if your application needn't simultaneously handle two CRC */ +/* polynomials. (Note, however, that XMODEM is strange.) */ +/* */ +/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */ +/* of course, 32-bit entries work OK if the high 16 bits are zero. */ +/* */ +/* 4. The values must be right-shifted by eight bits by the "updcrc" */ +/* logic; the shift must be unsigned (bring in zeroes). On some */ +/* hardware you could probably optimize the shift in assembler by */ +/* using byte-swap instructions. */ + +static const uint32_t crc_32_tab[] = { /* CRC polynomial 0xedb88320 */ +0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, +0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, +0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, +0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, +0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, +0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, +0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, +0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, +0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, +0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, +0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, +0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, +0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, +0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, +0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, +0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, +0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, +0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, +0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, +0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, +0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, +0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, +0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, +0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, +0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, +0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, +0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, +0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, +0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, +0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, +0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, +0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, +0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, +0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, +0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, +0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, +0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, +0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, +0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, +0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, +0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, +0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, +0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +#define UPDC32(octet,crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8)) + +uint32_t crc32buf(char *buf, size_t len) +{ + uint32_t crc; + + crc = 0xFFFFFFFF; + + for ( ; len; --len, ++buf) + { + crc = UPDC32(*buf, crc); + } + + return crc; +} diff --git a/obsolete-buildroot/sources/pppoecd-pathnames.patch b/obsolete-buildroot/sources/pppoecd-pathnames.patch deleted file mode 100644 index e6c1099674..0000000000 --- a/obsolete-buildroot/sources/pppoecd-pathnames.patch +++ /dev/null @@ -1,66 +0,0 @@ ---- pathnames.h.orig Tue Oct 14 03:09:53 2003 -+++ pathnames.h Sat Jul 10 21:04:34 2004 -@@ -9,37 +9,37 @@ - - #else /* HAVE_PATHS_H */ - #ifndef _PATH_VARRUN --#define _PATH_VARRUN "/tmp/ppp/" -+#define _PATH_VARRUN "/var/run" - #endif - #define _PATH_DEVNULL "/dev/null" - #endif /* HAVE_PATHS_H */ - - #ifndef _ROOT_PATH --#define _ROOT_PATH -+#define _ROOT_PATH "/etc" - #endif - --#define _PATH_UPAPFILE _ROOT_PATH "/tmp/ppp/pap-secrets" --#define _PATH_CHAPFILE _ROOT_PATH "/tmp/ppp/chap-secrets" --#define _PATH_SYSOPTIONS _ROOT_PATH "/tmp/ppp/options" --#define _PATH_IPUP _ROOT_PATH "/tmp/ppp/ip-up" --#define _PATH_IPDOWN _ROOT_PATH "/tmp/ppp/ip-down" --#define _PATH_AUTHUP _ROOT_PATH "/tmp/ppp/auth-up" --#define _PATH_AUTHDOWN _ROOT_PATH "/tmp/ppp/auth-down" --#define _PATH_TTYOPT _ROOT_PATH "/tmp/ppp/options." --#define _PATH_CONNERRS _ROOT_PATH "/tmp/ppp/connect-errors" --#define _PATH_PEERFILES _ROOT_PATH "/tmp/ppp/peers/" --#define _PATH_RESOLV _ROOT_PATH "/tmp/ppp/resolv.conf" -+#define _PATH_UPAPFILE _ROOT_PATH "/ppp/pap-secrets" -+#define _PATH_CHAPFILE _ROOT_PATH "/ppp/chap-secrets" -+#define _PATH_SYSOPTIONS _ROOT_PATH "/ppp/options" -+#define _PATH_IPUP _ROOT_PATH "/ppp/ip-up" -+#define _PATH_IPDOWN _ROOT_PATH "/ppp/ip-down" -+#define _PATH_AUTHUP _ROOT_PATH "/ppp/auth-up" -+#define _PATH_AUTHDOWN _ROOT_PATH "/ppp/auth-down" -+#define _PATH_TTYOPT _ROOT_PATH "/ppp/options." -+#define _PATH_CONNERRS "/tmp/connect-errors" -+#define _PATH_PEERFILES _ROOT_PATH "/ppp/peers/" -+#define _PATH_RESOLV "/tmp/resolv.conf" - - #define _PATH_USEROPT ".ppprc" - - #ifdef INET6 --#define _PATH_IPV6UP _ROOT_PATH "/tmp/ppp/ipv6-up" --#define _PATH_IPV6DOWN _ROOT_PATH "/tmp/ppp/ipv6-down" -+#define _PATH_IPV6UP _ROOT_PATH "/ppp/ipv6-up" -+#define _PATH_IPV6DOWN _ROOT_PATH "/ppp/ipv6-down" - #endif - - #ifdef IPX_CHANGE --#define _PATH_IPXUP _ROOT_PATH "/tmp/ppp/ipx-up" --#define _PATH_IPXDOWN _ROOT_PATH "/tmp/ppp/ipx-down" -+#define _PATH_IPXUP _ROOT_PATH "/ppp/ipx-up" -+#define _PATH_IPXDOWN _ROOT_PATH "/ppp/ipx-down" - #endif /* IPX_CHANGE */ - - #ifdef __STDC__ -@@ -48,7 +48,7 @@ - #ifdef HAVE_PATHS_H - #define _PATH_PPPDB "/var/run/pppd.tdb" - #else --#define _PATH_PPPDB "/tmp/ppp/pppd.tdb" -+#define _PATH_PPPDB "/tmp/pppd.tdb" - #endif - #endif /* __STDC__ */ - diff --git a/obsolete-buildroot/sources/pppoecd.conffiles b/obsolete-buildroot/sources/pppoecd.conffiles deleted file mode 100644 index 7ebe1156e0..0000000000 --- a/obsolete-buildroot/sources/pppoecd.conffiles +++ /dev/null @@ -1 +0,0 @@ -/etc/ppp/ip-up diff --git a/obsolete-buildroot/sources/pppoecd.control b/obsolete-buildroot/sources/pppoecd.control deleted file mode 100644 index 6996b8ecab..0000000000 --- a/obsolete-buildroot/sources/pppoecd.control +++ /dev/null @@ -1,10 +0,0 @@ -Package: pppoecd -Priority: optional -Version: 1.0 -Architecture: mipsel -Maintainer: below0 -Section: net -Source: Embedded in the main openwrt tarball -Description: Linksys PPPoE daemon for access to internet using DSL modems - - diff --git a/obsolete-buildroot/sources/pppoecd.ip-up b/obsolete-buildroot/sources/pppoecd.ip-up deleted file mode 100644 index da432949e7..0000000000 --- a/obsolete-buildroot/sources/pppoecd.ip-up +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -# set default route -/sbin/route add default gw $IPREMOTE - diff --git a/obsolete-buildroot/sources/pppoecd.patch b/obsolete-buildroot/sources/pppoecd.patch deleted file mode 100644 index 4fa4afc254..0000000000 --- a/obsolete-buildroot/sources/pppoecd.patch +++ /dev/null @@ -1,27 +0,0 @@ ---- pppoe.c.orig Sat Jul 10 20:55:38 2004 -+++ pppoe.c Sat Jul 10 20:55:55 2004 -@@ -131,8 +131,7 @@ - - if (pppoe_srv_name !=NULL) { - if (strlen (pppoe_srv_name) > 255) { -- poe_error (ses," Service name too long -- (maximum allowed 256 chars)"); -+ poe_error (ses," Service name too long (maximum allowed 256 chars)"); - poe_die(-1); - } - ses->filt->stag = make_filter_tag(PTT_SRV_NAME, ---- Makefile.orig Sun Jul 11 03:26:49 2004 -+++ Makefile Sun Jul 11 03:27:18 2004 -@@ -68,9 +68,9 @@ - all: pppoecd - - install: all -- install -d $(INSTALLDIR)/usr/sbin -- install -m 755 pppoecd $(INSTALLDIR)/usr/sbin -- $(STRIP) $(INSTALLDIR)/usr/sbin/pppoecd -+ install -d $(INSTALLDIR)/sbin -+ install -m 755 pppoecd $(INSTALLDIR)/sbin -+ $(STRIP) $(INSTALLDIR)/sbin/pppoecd - - pppoecd: $(OBJS) - $(LD) -r -o .$@ $^ $(LIBCRYPT) diff --git a/obsolete-buildroot/sources/pppoecd.postrm b/obsolete-buildroot/sources/pppoecd.postrm deleted file mode 100644 index 0d53d99f0f..0000000000 --- a/obsolete-buildroot/sources/pppoecd.postrm +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/sh - -rm -rf /etc/ppp - diff --git a/obsolete-buildroot/sources/target_skeleton/etc/TZ b/obsolete-buildroot/sources/target_skeleton/etc/TZ deleted file mode 100644 index 9fcb2a3c56..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/TZ +++ /dev/null @@ -1 +0,0 @@ -MST7MDT diff --git a/obsolete-buildroot/sources/target_skeleton/etc/fstab b/obsolete-buildroot/sources/target_skeleton/etc/fstab deleted file mode 100644 index 6d33629a7b..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/fstab +++ /dev/null @@ -1,8 +0,0 @@ -# /etc/fstab: static file system information. -# -# -/dev/root / ext2 rw,noauto 0 1 -proc /proc proc defaults 0 0 -devpts /dev/pts devpts defaults,gid=5,mode=620 0 0 -tmpfs /tmp tmpfs defaults 0 0 - diff --git a/obsolete-buildroot/sources/target_skeleton/etc/group b/obsolete-buildroot/sources/target_skeleton/etc/group deleted file mode 100644 index a21ef0f769..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/group +++ /dev/null @@ -1,10 +0,0 @@ -root:x:0: -daemon:x:1: -bin:x:2: -sys:x:3: -adm:x:4: -tty:x:5: -disk:x:6: -utmp:x:43: -staff:x:50: -default:x:1000: diff --git a/obsolete-buildroot/sources/target_skeleton/etc/hostname b/obsolete-buildroot/sources/target_skeleton/etc/hostname deleted file mode 100644 index 52e67d68aa..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/hostname +++ /dev/null @@ -1 +0,0 @@ -uclibc diff --git a/obsolete-buildroot/sources/target_skeleton/etc/hosts b/obsolete-buildroot/sources/target_skeleton/etc/hosts deleted file mode 100644 index ba712fe033..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/hosts +++ /dev/null @@ -1 +0,0 @@ -127.0.0.1 localhost diff --git a/obsolete-buildroot/sources/target_skeleton/etc/init.d/S20urandom b/obsolete-buildroot/sources/target_skeleton/etc/init.d/S20urandom deleted file mode 100755 index 433fafee4e..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/init.d/S20urandom +++ /dev/null @@ -1,44 +0,0 @@ -#! /bin/sh -# -# urandom This script saves the random seed between reboots. -# It is called from the boot, halt and reboot scripts. -# -# Version: @(#)urandom 1.33 22-Jun-1998 miquels@cistron.nl -# - -[ -c /dev/urandom ] || exit 0 -#. /etc/default/rcS - -case "$1" in - start|"") - if [ "$VERBOSE" != no ] - then - echo -n "Initializing random number generator... " - fi - # Load and then save 512 bytes, - # which is the size of the entropy pool - if [ -f /etc/random-seed ] - then - cat /etc/random-seed >/dev/urandom - fi - rm -f /etc/random-seed - umask 077 - dd if=/dev/urandom of=/etc/random-seed count=1 \ - >/dev/null 2>&1 || echo "urandom start: failed." - umask 022 - [ "$VERBOSE" != no ] && echo "done." - ;; - stop) - # Carry a random seed from shut-down to start-up; - # see documentation in linux/drivers/char/random.c - [ "$VERBOSE" != no ] && echo -n "Saving random seed... " - umask 077 - dd if=/dev/urandom of=/etc/random-seed count=1 \ - >/dev/null 2>&1 || echo "urandom stop: failed." - [ "$VERBOSE" != no ] && echo "done." - ;; - *) - echo "Usage: urandom {start|stop}" >&2 - exit 1 - ;; -esac diff --git a/obsolete-buildroot/sources/target_skeleton/etc/init.d/S40network b/obsolete-buildroot/sources/target_skeleton/etc/init.d/S40network deleted file mode 100755 index d835d9c72a..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/init.d/S40network +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh -# -# Start the network.... -# - -start() { - echo "Starting network..." - /sbin/ifup -a -} -stop() { - echo -n "Stopping network..." - /sbin/ifdown -a -} -restart() { - stop - start -} - -case "$1" in - start) - start - ;; - stop) - stop - ;; - restart|reload) - restart - ;; - *) - echo $"Usage: $0 {start|stop|restart}" - exit 1 -esac - -exit $? - diff --git a/obsolete-buildroot/sources/target_skeleton/etc/init.d/rcS b/obsolete-buildroot/sources/target_skeleton/etc/init.d/rcS deleted file mode 100755 index de411534da..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/init.d/rcS +++ /dev/null @@ -1,27 +0,0 @@ -#!/bin/sh - - -# Start all init scripts in /etc/init.d -# executing them in numerical order. -# -for i in /etc/init.d/S??* ;do - - # Ignore dangling symlinks (if any). - [ ! -f "$i" ] && continue - - case "$i" in - *.sh) - # Source shell script for speed. - ( - trap - INT QUIT TSTP - set start - . $i - ) - ;; - *) - # No sh extension, so fork subprocess. - $i start - ;; - esac -done - diff --git a/obsolete-buildroot/sources/target_skeleton/etc/inittab b/obsolete-buildroot/sources/target_skeleton/etc/inittab deleted file mode 100644 index a6c014e751..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/inittab +++ /dev/null @@ -1,47 +0,0 @@ -# /etc/inittab -# -# Copyright (C) 2001 Erik Andersen -# -# Note: BusyBox init doesn't support runlevels. The runlevels field is -# completely ignored by BusyBox init. If you want runlevels, use -# sysvinit. -# -# Format for each entry: ::: -# -# id == tty to run on, or empty for /dev/console -# runlevels == ignored -# action == one of sysinit, respawn, askfirst, wait, and once -# process == program to run - -# Startup the system -null::sysinit:/bin/mount -o remount,rw / -null::sysinit:/bin/mount -t proc proc /proc -null::sysinit:/bin/mount -a -null::sysinit:/bin/hostname -F /etc/hostname -null::sysinit:/sbin/ifconfig lo 127.0.0.1 up -null::sysinit:/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo -# now run any rc scripts -::sysinit:/etc/init.d/rcS - -# Set up a couple of getty's -tty1::respawn:/sbin/getty 38400 tty1 -tty2::respawn:/sbin/getty 38400 tty2 - -# Put a getty on the serial port -#ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100 - -# Logging junk -null::sysinit:/bin/touch /var/log/messages -null::respawn:/sbin/syslogd -n -m 0 -null::respawn:/sbin/klogd -n -tty3::respawn:/usr/bin/tail -f /var/log/messages - -# Stuff to do for the 3-finger salute -::ctrlaltdel:/sbin/reboot - -# Stuff to do before rebooting -null::shutdown:/usr/bin/killall klogd -null::shutdown:/usr/bin/killall syslogd -null::shutdown:/bin/umount -a -r -null::shutdown:/sbin/swapoff -a - diff --git a/obsolete-buildroot/sources/target_skeleton/etc/inputrc b/obsolete-buildroot/sources/target_skeleton/etc/inputrc deleted file mode 100644 index 2f1cb601a5..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/inputrc +++ /dev/null @@ -1,44 +0,0 @@ -# /etc/inputrc - global inputrc for libreadline -# See readline(3readline) and `info readline' for more information. - -# Be 8 bit clean. -set input-meta on -set output-meta on -set bell-style visible - -# To allow the use of 8bit-characters like the german umlauts, comment out -# the line below. However this makes the meta key not work as a meta key, -# which is annoying to those which don't need to type in 8-bit characters. - -# set convert-meta off - -"\e0d": backward-word -"\e0c": forward-word -"\e[h": beginning-of-line -"\e[f": end-of-line -"\e[1~": beginning-of-line -"\e[4~": end-of-line -#"\e[5~": beginning-of-history -#"\e[6~": end-of-history -"\e[3~": delete-char -"\e[2~": quoted-insert - -# Common standard keypad and cursor -# (codes courtsey Werner Fink, ) -#"\e[1~": history-search-backward -"\e[2~": yank -"\e[3~": delete-char -#"\e[4~": set-mark -"\e[5~": history-search-backward -"\e[6~": history-search-forward -# Normal keypad and cursor of xterm -"\e[F": end-of-line -"\e[H": beginning-of-line -# Application keypad and cursor of xterm -"\eOA": previous-history -"\eOC": forward-char -"\eOB": next-history -"\eOD": backward-char -"\eOF": end-of-line -"\eOH": beginning-of-line - diff --git a/obsolete-buildroot/sources/target_skeleton/etc/issue b/obsolete-buildroot/sources/target_skeleton/etc/issue deleted file mode 100644 index f24b862c97..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/issue +++ /dev/null @@ -1,4 +0,0 @@ - - -Welcome to the Erik's uClibc development environment. - diff --git a/obsolete-buildroot/sources/target_skeleton/etc/network/interfaces b/obsolete-buildroot/sources/target_skeleton/etc/network/interfaces deleted file mode 100644 index 218b82cde5..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/network/interfaces +++ /dev/null @@ -1,4 +0,0 @@ -# Configure Loopback -auto lo -iface lo inet loopback - diff --git a/obsolete-buildroot/sources/target_skeleton/etc/passwd b/obsolete-buildroot/sources/target_skeleton/etc/passwd deleted file mode 100644 index e0f473fc7b..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/passwd +++ /dev/null @@ -1,13 +0,0 @@ -root:x:0:0:root:/root:/bin/sh -daemon:x:1:1:daemon:/usr/sbin:/bin/sh -bin:x:2:2:bin:/bin:/bin/sh -sys:x:3:3:sys:/dev:/bin/sh -sync:x:4:100:sync:/bin:/bin/sync -mail:x:8:8:mail:/var/spool/mail:/bin/sh -proxy:x:13:13:proxy:/bin:/bin/sh -www-data:x:33:33:www-data:/var/www:/bin/sh -backup:x:34:34:backup:/var/backups:/bin/sh -operator:x:37:37:Operator:/var:/bin/sh -sshd:x:103:99:Operator:/var:/bin/sh -nobody:x:99:99:nobody:/home:/bin/sh -default:x:1000:1000:Default non-root user:/home/default:/bin/sh diff --git a/obsolete-buildroot/sources/target_skeleton/etc/profile b/obsolete-buildroot/sources/target_skeleton/etc/profile deleted file mode 100644 index cc2e0beb87..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/profile +++ /dev/null @@ -1,48 +0,0 @@ -# ~/.bashrc: executed by bash(1) for non-login interactive shells. - -export PATH=\ -/bin:\ -/sbin:\ -/usr/bin:\ -/usr/sbin:\ -/usr/bin/X11:\ -/usr/local/bin - -# If running interactively, then: -if [ "$PS1" ]; then - - if [ "$BASH" ]; then - export PS1="[\u@\h \W]\\$ " - alias ll='/bin/ls --color=tty -laFh' - alias ls='/bin/ls --color=tty -F' - export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.png=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:'; - else - if [ "`id -u`" -eq 0 ]; then - export PS1='# ' - else - export PS1='$ ' - fi - fi - - export USER=`id -un` - export LOGNAME=$USER - export HOSTNAME=`/bin/hostname` - export HISTSIZE=1000 - export HISTFILESIZE=1000 - export PAGER='/bin/more ' - export EDITOR='/bin/vi' - export INPUTRC=/etc/inputrc - export DMALLOC_OPTIONS=debug=0x34f47d83,inter=100,log=logfile - - ### Some aliases - alias ps2='ps facux ' - alias ps1='ps faxo "%U %t %p %a" ' - alias af='ps af' - alias cls='clear' - alias df='df -h' - alias indent='indent -bad -bap -bbo -nbc -br -brs -c33 -cd33 -ncdb -ce -ci4 -cli0 -cp33 -cs -d0 -di1 -nfc1 -nfca -hnl -i4 -ip0 -l75 -lp -npcs -npsl -nsc -nsob -nss -ts4 ' - #alias bc='bc -l' - alias minicom='minicom -c on' - alias calc='calc -Cd ' - alias bc='calc -Cd ' -fi; diff --git a/obsolete-buildroot/sources/target_skeleton/etc/protocols b/obsolete-buildroot/sources/target_skeleton/etc/protocols deleted file mode 100644 index 98f9f2d30e..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/protocols +++ /dev/null @@ -1,31 +0,0 @@ -# /etc/protocols: -# $Id$ -# -# Internet (IP) protocols -# -# from: @(#)protocols 5.1 (Berkeley) 4/17/89 -# -# Updated for NetBSD based on RFC 1340, Assigned Numbers (July 1992). - -ip 0 IP # internet protocol, pseudo protocol number -icmp 1 ICMP # internet control message protocol -igmp 2 IGMP # Internet Group Management -ggp 3 GGP # gateway-gateway protocol -ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'') -st 5 ST # ST datagram mode -tcp 6 TCP # transmission control protocol -egp 8 EGP # exterior gateway protocol -pup 12 PUP # PARC universal packet protocol -udp 17 UDP # user datagram protocol -hmp 20 HMP # host monitoring protocol -xns-idp 22 XNS-IDP # Xerox NS IDP -rdp 27 RDP # "reliable datagram" protocol -iso-tp4 29 ISO-TP4 # ISO Transport Protocol class 4 -xtp 36 XTP # Xpress Tranfer Protocol -ddp 37 DDP # Datagram Delivery Protocol -idpr-cmtp 39 IDPR-CMTP # IDPR Control Message Transport -rspf 73 RSPF #Radio Shortest Path First. -vmtp 81 VMTP # Versatile Message Transport -ospf 89 OSPFIGP # Open Shortest Path First IGP -ipip 94 IPIP # Yet Another IP encapsulation -encap 98 ENCAP # Yet Another IP encapsulation diff --git a/obsolete-buildroot/sources/target_skeleton/etc/random-seed b/obsolete-buildroot/sources/target_skeleton/etc/random-seed deleted file mode 100644 index fbc7352fbb..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/etc/random-seed and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/etc/resolv.conf b/obsolete-buildroot/sources/target_skeleton/etc/resolv.conf deleted file mode 100644 index 71a86dd76c..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/resolv.conf +++ /dev/null @@ -1,2 +0,0 @@ -domain dev.null -nameserver 127.0.0.1 diff --git a/obsolete-buildroot/sources/target_skeleton/etc/securetty b/obsolete-buildroot/sources/target_skeleton/etc/securetty deleted file mode 100644 index 81616f38ea..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/securetty +++ /dev/null @@ -1,12 +0,0 @@ -tty1 -tty2 -tty3 -tty4 -tty5 -tty6 -tty7 -tty8 -ttyS0 -ttyS1 -ttyS2 -ttyS3 diff --git a/obsolete-buildroot/sources/target_skeleton/etc/services b/obsolete-buildroot/sources/target_skeleton/etc/services deleted file mode 100644 index 13718ef3de..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/services +++ /dev/null @@ -1,302 +0,0 @@ -# /etc/services: -# $Id$ -# -# Network services, Internet style -# -# Note that it is presently the policy of IANA to assign a single well-known -# port number for both TCP and UDP; hence, most entries here have two entries -# even if the protocol doesn't support UDP operations. -# Updated from RFC 1700, ``Assigned Numbers'' (October 1994). Not all ports -# are included, only the more common ones. - -tcpmux 1/tcp # TCP port service multiplexer -echo 7/tcp -echo 7/udp -discard 9/tcp sink null -discard 9/udp sink null -systat 11/tcp users -daytime 13/tcp -daytime 13/udp -netstat 15/tcp -qotd 17/tcp quote -msp 18/tcp # message send protocol -msp 18/udp # message send protocol -chargen 19/tcp ttytst source -chargen 19/udp ttytst source -ftp-data 20/tcp -ftp 21/tcp -fsp 21/udp fspd -ssh 22/tcp # SSH Remote Login Protocol -ssh 22/udp # SSH Remote Login Protocol -telnet 23/tcp -# 24 - private -smtp 25/tcp mail -# 26 - unassigned -time 37/tcp timserver -time 37/udp timserver -rlp 39/udp resource # resource location -nameserver 42/tcp name # IEN 116 -whois 43/tcp nicname -re-mail-ck 50/tcp # Remote Mail Checking Protocol -re-mail-ck 50/udp # Remote Mail Checking Protocol -domain 53/tcp nameserver # name-domain server -domain 53/udp nameserver -mtp 57/tcp # deprecated -bootps 67/tcp # BOOTP server -bootps 67/udp -bootpc 68/tcp # BOOTP client -bootpc 68/udp -tftp 69/udp -gopher 70/tcp # Internet Gopher -gopher 70/udp -rje 77/tcp netrjs -finger 79/tcp -www 80/tcp http # WorldWideWeb HTTP -www 80/udp # HyperText Transfer Protocol -link 87/tcp ttylink -kerberos 88/tcp kerberos5 krb5 # Kerberos v5 -kerberos 88/udp kerberos5 krb5 # Kerberos v5 -supdup 95/tcp -# 100 - reserved -hostnames 101/tcp hostname # usually from sri-nic -iso-tsap 102/tcp tsap # part of ISODE. -csnet-ns 105/tcp cso-ns # also used by CSO name server -csnet-ns 105/udp cso-ns -# unfortunately the poppassd (Eudora) uses a port which has already -# been assigned to a different service. We list the poppassd as an -# alias here. This should work for programs asking for this service. -# (due to a bug in inetd the 3com-tsmux line is disabled) -#3com-tsmux 106/tcp poppassd -#3com-tsmux 106/udp poppassd -rtelnet 107/tcp # Remote Telnet -rtelnet 107/udp -pop-2 109/tcp postoffice # POP version 2 -pop-2 109/udp -pop-3 110/tcp # POP version 3 -pop-3 110/udp -sunrpc 111/tcp portmapper # RPC 4.0 portmapper TCP -sunrpc 111/udp portmapper # RPC 4.0 portmapper UDP -auth 113/tcp authentication tap ident -sftp 115/tcp -uucp-path 117/tcp -nntp 119/tcp readnews untp # USENET News Transfer Protocol -ntp 123/tcp -ntp 123/udp # Network Time Protocol -netbios-ns 137/tcp # NETBIOS Name Service -netbios-ns 137/udp -netbios-dgm 138/tcp # NETBIOS Datagram Service -netbios-dgm 138/udp -netbios-ssn 139/tcp # NETBIOS session service -netbios-ssn 139/udp -imap2 143/tcp # Interim Mail Access Proto v2 -imap2 143/udp -snmp 161/udp # Simple Net Mgmt Proto -snmp-trap 162/udp snmptrap # Traps for SNMP -cmip-man 163/tcp # ISO mgmt over IP (CMOT) -cmip-man 163/udp -cmip-agent 164/tcp -cmip-agent 164/udp -xdmcp 177/tcp # X Display Mgr. Control Proto -xdmcp 177/udp -nextstep 178/tcp NeXTStep NextStep # NeXTStep window -nextstep 178/udp NeXTStep NextStep # server -bgp 179/tcp # Border Gateway Proto. -bgp 179/udp -prospero 191/tcp # Cliff Neuman's Prospero -prospero 191/udp -irc 194/tcp # Internet Relay Chat -irc 194/udp -smux 199/tcp # SNMP Unix Multiplexer -smux 199/udp -at-rtmp 201/tcp # AppleTalk routing -at-rtmp 201/udp -at-nbp 202/tcp # AppleTalk name binding -at-nbp 202/udp -at-echo 204/tcp # AppleTalk echo -at-echo 204/udp -at-zis 206/tcp # AppleTalk zone information -at-zis 206/udp -qmtp 209/tcp # The Quick Mail Transfer Protocol -qmtp 209/udp # The Quick Mail Transfer Protocol -z3950 210/tcp wais # NISO Z39.50 database -z3950 210/udp wais -ipx 213/tcp # IPX -ipx 213/udp -imap3 220/tcp # Interactive Mail Access -imap3 220/udp # Protocol v3 -ulistserv 372/tcp # UNIX Listserv -ulistserv 372/udp -https 443/tcp # MCom -https 443/udp # MCom -snpp 444/tcp # Simple Network Paging Protocol -snpp 444/udp # Simple Network Paging Protocol -saft 487/tcp # Simple Asynchronous File Transfer -saft 487/udp # Simple Asynchronous File Transfer -npmp-local 610/tcp dqs313_qmaster # npmp-local / DQS -npmp-local 610/udp dqs313_qmaster # npmp-local / DQS -npmp-gui 611/tcp dqs313_execd # npmp-gui / DQS -npmp-gui 611/udp dqs313_execd # npmp-gui / DQS -hmmp-ind 612/tcp dqs313_intercell# HMMP Indication / DQS -hmmp-ind 612/udp dqs313_intercell# HMMP Indication / DQS -# -# UNIX specific services -# -exec 512/tcp -biff 512/udp comsat -login 513/tcp -who 513/udp whod -shell 514/tcp cmd # no passwords used -syslog 514/udp -printer 515/tcp spooler # line printer spooler -talk 517/udp -ntalk 518/udp -route 520/udp router routed # RIP -timed 525/udp timeserver -tempo 526/tcp newdate -courier 530/tcp rpc -conference 531/tcp chat -netnews 532/tcp readnews -netwall 533/udp # -for emergency broadcasts -uucp 540/tcp uucpd # uucp daemon -afpovertcp 548/tcp # AFP over TCP -afpovertcp 548/udp # AFP over TCP -remotefs 556/tcp rfs_server rfs # Brunhoff remote filesystem -klogin 543/tcp # Kerberized `rlogin' (v5) -kshell 544/tcp krcmd # Kerberized `rsh' (v5) -kerberos-adm 749/tcp # Kerberos `kadmin' (v5) -# -webster 765/tcp # Network dictionary -webster 765/udp -# -# From ``Assigned Numbers'': -# -#> The Registered Ports are not controlled by the IANA and on most systems -#> can be used by ordinary user processes or programs executed by ordinary -#> users. -# -#> Ports are used in the TCP [45,106] to name the ends of logical -#> connections which carry long term conversations. For the purpose of -#> providing services to unknown callers, a service contact port is -#> defined. This list specifies the port used by the server process as its -#> contact port. While the IANA can not control uses of these ports it -#> does register or list uses of these ports as a convienence to the -#> community. -# -nfsdstatus 1110/tcp -nfsd-keepalive 1110/udp - -ingreslock 1524/tcp -ingreslock 1524/udp -prospero-np 1525/tcp # Prospero non-privileged -prospero-np 1525/udp -datametrics 1645/tcp old-radius # datametrics / old radius entry -datametrics 1645/udp old-radius # datametrics / old radius entry -sa-msg-port 1646/tcp old-radacct # sa-msg-port / old radacct entry -sa-msg-port 1646/udp old-radacct # sa-msg-port / old radacct entry -radius 1812/tcp # Radius -radius 1812/udp # Radius -radacct 1813/tcp # Radius Accounting -radacct 1813/udp # Radius Accounting -nfsd 2049/tcp nfs -nfsd 2049/udp nfs -cvspserver 2401/tcp # CVS client/server operations -cvspserver 2401/udp # CVS client/server operations -mysql 3306/tcp # MySQL -mysql 3306/udp # MySQL -rfe 5002/tcp # Radio Free Ethernet -rfe 5002/udp # Actually uses UDP only -cfengine 5308/tcp # CFengine -cfengine 5308/udp # CFengine -bbs 7000/tcp # BBS service -# -# -# Kerberos (Project Athena/MIT) services -# Note that these are for Kerberos v4, and are unofficial. Sites running -# v4 should uncomment these and comment out the v5 entries above. -# -kerberos4 750/udp kerberos-iv kdc # Kerberos (server) udp -kerberos4 750/tcp kerberos-iv kdc # Kerberos (server) tcp -kerberos_master 751/udp # Kerberos authentication -kerberos_master 751/tcp # Kerberos authentication -passwd_server 752/udp # Kerberos passwd server -krb_prop 754/tcp # Kerberos slave propagation -krbupdate 760/tcp kreg # Kerberos registration -kpasswd 761/tcp kpwd # Kerberos "passwd" -kpop 1109/tcp # Pop with Kerberos -knetd 2053/tcp # Kerberos de-multiplexor -zephyr-srv 2102/udp # Zephyr server -zephyr-clt 2103/udp # Zephyr serv-hm connection -zephyr-hm 2104/udp # Zephyr hostmanager -eklogin 2105/tcp # Kerberos encrypted rlogin -# -# Unofficial but necessary (for NetBSD) services -# -supfilesrv 871/tcp # SUP server -supfiledbg 1127/tcp # SUP debugging -# -# Datagram Delivery Protocol services -# -rtmp 1/ddp # Routing Table Maintenance Protocol -nbp 2/ddp # Name Binding Protocol -echo 4/ddp # AppleTalk Echo Protocol -zip 6/ddp # Zone Information Protocol -# -# Services added for the Debian GNU/Linux distribution -poppassd 106/tcp # Eudora -poppassd 106/udp # Eudora -mailq 174/tcp # Mailer transport queue for Zmailer -mailq 174/tcp # Mailer transport queue for Zmailer -omirr 808/tcp omirrd # online mirror -omirr 808/udp omirrd # online mirror -rmtcfg 1236/tcp # Gracilis Packeten remote config server -xtel 1313/tcp # french minitel -coda_opcons 1355/udp # Coda opcons (Coda fs) -coda_venus 1363/udp # Coda venus (Coda fs) -coda_auth 1357/udp # Coda auth (Coda fs) -coda_udpsrv 1359/udp # Coda udpsrv (Coda fs) -coda_filesrv 1361/udp # Coda filesrv (Coda fs) -codacon 1423/tcp venus.cmu # Coda Console (Coda fs) -coda_aux1 1431/tcp # coda auxiliary service (Coda fs) -coda_aux1 1431/udp # coda auxiliary service (Coda fs) -coda_aux2 1433/tcp # coda auxiliary service (Coda fs) -coda_aux2 1433/udp # coda auxiliary service (Coda fs) -coda_aux3 1435/tcp # coda auxiliary service (Coda fs) -coda_aux3 1435/udp # coda auxiliary service (Coda fs) -cfinger 2003/tcp # GNU Finger -afbackup 2988/tcp # Afbackup system -afbackup 2988/udp # Afbackup system -icp 3130/tcp # Internet Cache Protocol (Squid) -icp 3130/udp # Internet Cache Protocol (Squid) -postgres 5432/tcp # POSTGRES -postgres 5432/udp # POSTGRES -fax 4557/tcp # FAX transmission service (old) -hylafax 4559/tcp # HylaFAX client-server protocol (new) -noclog 5354/tcp # noclogd with TCP (nocol) -noclog 5354/udp # noclogd with UDP (nocol) -hostmon 5355/tcp # hostmon uses TCP (nocol) -hostmon 5355/udp # hostmon uses TCP (nocol) -ircd 6667/tcp # Internet Relay Chat -ircd 6667/udp # Internet Relay Chat -webcache 8080/tcp # WWW caching service -webcache 8080/udp # WWW caching service -tproxy 8081/tcp # Transparent Proxy -tproxy 8081/udp # Transparent Proxy -mandelspawn 9359/udp mandelbrot # network mandelbrot -amanda 10080/udp # amanda backup services -amandaidx 10082/tcp # amanda backup services -amidxtape 10083/tcp # amanda backup services -isdnlog 20011/tcp # isdn logging system -isdnlog 20011/udp # isdn logging system -vboxd 20012/tcp # voice box system -vboxd 20012/udp # voice box system -binkp 24554/tcp # Binkley -binkp 24554/udp # Binkley -asp 27374/tcp # Address Search Protocol -asp 27374/udp # Address Search Protocol -tfido 60177/tcp # Ifmail -tfido 60177/udp # Ifmail -fido 60179/tcp # Ifmail -fido 60179/udp # Ifmail - -# Local services - diff --git a/obsolete-buildroot/sources/target_skeleton/etc/shadow b/obsolete-buildroot/sources/target_skeleton/etc/shadow deleted file mode 100644 index 4941a1ac53..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/etc/shadow +++ /dev/null @@ -1,12 +0,0 @@ -root::10933:0:99999:7::: -bin:*:10933:0:99999:7::: -daemon:*:10933:0:99999:7::: -adm:*:10933:0:99999:7::: -lp:*:10933:0:99999:7::: -sync:*:10933:0:99999:7::: -shutdown:*:10933:0:99999:7::: -halt:*:10933:0:99999:7::: -uucp:*:10933:0:99999:7::: -operator:*:10933:0:99999:7::: -nobody:*:10933:0:99999:7::: -default::10933:0:99999:7::: diff --git a/obsolete-buildroot/sources/target_skeleton/root/.bash_history b/obsolete-buildroot/sources/target_skeleton/root/.bash_history deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/obsolete-buildroot/sources/target_skeleton/root/.bash_logout b/obsolete-buildroot/sources/target_skeleton/root/.bash_logout deleted file mode 100644 index 77ef1f9508..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/root/.bash_logout +++ /dev/null @@ -1,7 +0,0 @@ -# ~/.bash_logout: executed by bash(1) when login shell exits. - -# when leaving the console clear the screen to increase privacy - -case "`tty`" in - /dev/tty[0-9]*) clear -esac diff --git a/obsolete-buildroot/sources/target_skeleton/root/.bash_profile b/obsolete-buildroot/sources/target_skeleton/root/.bash_profile deleted file mode 100644 index 27bf14953d..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/root/.bash_profile +++ /dev/null @@ -1,15 +0,0 @@ -# .bash_profile - -export PATH=\ -/bin:\ -/sbin:\ -/usr/bin:\ -/usr/sbin:\ -/usr/bin/X11:\ -/usr/local/bin - -umask 022 - -if [ -f ~/.bashrc ]; then - source ~/.bashrc -fi diff --git a/obsolete-buildroot/sources/target_skeleton/root/.bashrc b/obsolete-buildroot/sources/target_skeleton/root/.bashrc deleted file mode 100644 index d13c8f9026..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/root/.bashrc +++ /dev/null @@ -1,48 +0,0 @@ -# ~/.bashrc: executed by bash(1) for non-login interactive shells. - -export PATH=\ -/bin:\ -/sbin:\ -/usr/bin:\ -/usr/sbin:\ -/usr/bin/X11:\ -/usr/local/bin - -# If running interactively, then: -if [ "$PS1" ]; then - - if [ "$BASH" ]; then - export PS1="[\u@\h \W]\\$ " - else - if [ "`id -u`" -eq 0 ]; then - export PS1='# ' - else - export PS1='$ ' - fi - fi - - export USER=`id -un` - export LOGNAME=$USER - export HOSTNAME=`/bin/hostname` - export HISTSIZE=1000 - export HISTFILESIZE=1000 - export PAGER='/bin/more ' - export EDITOR='/bin/vi' - export INPUTRC=/etc/inputrc - export DMALLOC_OPTIONS=debug=0x34f47d83,inter=100,log=logfile - export LS_COLORS='no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.jpg=01;35:*.jpeg=01;35:*.png=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.mpg=01;35:*.mpeg=01;35:*.avi=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:'; - - ### Some aliases - alias ps2='ps facux ' - alias ps1='ps faxo "%U %t %p %a" ' - alias af='ps af' - alias cls='clear' - alias ll='/bin/ls --color=tty -laFh' - alias ls='/bin/ls --color=tty -F' - alias df='df -h' - alias indent='indent -bad -bap -bbo -nbc -br -brs -c33 -cd33 -ncdb -ce -ci4 -cli0 -cp33 -cs -d0 -di1 -nfc1 -nfca -hnl -i4 -ip0 -l75 -lp -npcs -npsl -nsc -nsob -nss -ts4 ' - #alias bc='bc -l' - alias minicom='minicom -c on' - alias calc='calc -Cd ' - alias bc='calc -Cd ' -fi; diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/a/ansi b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/a/ansi deleted file mode 100644 index d1e14008c5..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/a/ansi and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/d/dumb b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/d/dumb deleted file mode 100644 index ffdc8acf34..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/d/dumb and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/l/linux b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/l/linux deleted file mode 100644 index e9ec115d5c..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/l/linux and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/r/rxvt b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/r/rxvt deleted file mode 100644 index ba6987a1a8..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/r/rxvt and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/s/screen b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/s/screen deleted file mode 100644 index 8f4206c81e..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/s/screen and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/s/screen-w b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/s/screen-w deleted file mode 100644 index 965601433d..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/s/screen-w and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/s/sun b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/s/sun deleted file mode 100644 index 47c0d66faa..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/s/sun and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/v/vt100 b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/v/vt100 deleted file mode 100644 index 5cc9a88bb0..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/v/vt100 and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/v/vt220 b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/v/vt220 deleted file mode 100644 index cefb7b3587..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/v/vt220 and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/v/vt52 b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/v/vt52 deleted file mode 100644 index d55932876a..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/v/vt52 and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/x/xterm b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/x/xterm deleted file mode 100644 index 89da67d089..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/x/xterm and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/x/xterm-xfree86 b/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/x/xterm-xfree86 deleted file mode 100644 index eeac9d8d35..0000000000 Binary files a/obsolete-buildroot/sources/target_skeleton/usr/share/terminfo/x/xterm-xfree86 and /dev/null differ diff --git a/obsolete-buildroot/sources/target_skeleton/usr/share/udhcpc/default.script b/obsolete-buildroot/sources/target_skeleton/usr/share/udhcpc/default.script deleted file mode 100755 index a52a7f8122..0000000000 --- a/obsolete-buildroot/sources/target_skeleton/usr/share/udhcpc/default.script +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -# udhcpc script edited by Tim Riker - -[ -z "$1" ] && echo "Error: should be called from udhcpc" && exit 1 - -RESOLV_CONF="/etc/resolv.conf" -[ -n "$broadcast" ] && BROADCAST="broadcast $broadcast" -[ -n "$subnet" ] && NETMASK="netmask $subnet" - -case "$1" in - deconfig) - /sbin/ifconfig $interface 0.0.0.0 - ;; - - renew|bound) - /sbin/ifconfig $interface $ip $BROADCAST $NETMASK - - if [ -n "$router" ] ; then - echo "deleting routers" - while route del default gw 0.0.0.0 dev $interface ; do - : - done - - for i in $router ; do - route add default gw $i dev $interface - done - fi - - echo -n > $RESOLV_CONF - [ -n "$domain" ] && echo search $domain >> $RESOLV_CONF - for i in $dns ; do - echo adding dns $i - echo nameserver $i >> $RESOLV_CONF - done - ;; -esac - -exit 0