Unseparated changes for Openswan support, net changes, bridge
enhancements, etc.

---

 Documentation/Configure.help       |   53 ++++++++++++++++++++
 Makefile                           |   49 ++++++++++++++----
 Rules.make                         |    5 +
 arch/i386/boot/compressed/Makefile |    2 
 arch/i386/defconfig                |   97 +++++++++++++++++++++++++++++++++++++
 drivers/char/Makefile              |    4 -
 drivers/char/serial.c              |    2 
 drivers/pci/proc.c                 |   14 ++++-
 fs/partitions/check.c              |    2 
 include/asm-i386/io.h              |    2 
 include/asm-i386/page.h            |   10 +++
 include/linux/blkdev.h             |    6 +-
 include/linux/netdevice.h          |    9 ++-
 include/linux/netfilter.h          |   12 +++-
 include/linux/netfilter_ipv4.h     |    1 
 include/linux/proc_fs.h            |    1 
 include/linux/skbuff.h             |   31 +++++++++++
 include/linux/sysctl.h             |    7 ++
 include/net/arp.h                  |    7 ++
 include/net/ip.h                   |    8 +++
 include/net/route.h                |    5 +
 include/net/sock.h                 |   14 +++++
 include/net/tcp.h                  |    6 ++
 kernel/module.c                    |    8 +++
 net/8021q/vlan.c                   |    2 
 net/Config.in                      |   16 ++++++
 net/Makefile                       |    1 
 net/bridge/br.c                    |    8 +++
 net/bridge/br_forward.c            |   53 ++++++++++++++++++--
 net/bridge/br_if.c                 |    2 
 net/bridge/br_input.c              |    5 -
 net/bridge/br_private.h            |    8 +++
 net/core/dev.c                     |   14 +++++
 net/core/netfilter.c               |   14 +++--
 net/core/skbuff.c                  |    4 +
 net/ipv4/af_inet.c                 |   16 ++++++
 net/ipv4/arp.c                     |   62 ++++++++++++++++++++++-
 net/ipv4/ip_output.c               |   17 ++++++
 net/ipv4/route.c                   |   25 +++++++++
 net/ipv4/syncookies.c              |    3 +
 net/ipv4/sysctl_net_ipv4.c         |   11 ++++
 net/ipv4/tcp.c                     |    7 ++
 net/ipv4/tcp_ipv4.c                |   29 +++++++++++
 net/ipv4/tcp_output.c              |    4 +
 net/ipv4/udp.c                     |   84 ++++++++++++++++++++++++++++++++
 net/netsyms.c                      |   12 ++++
 46 files changed, 706 insertions(+), 46 deletions(-)

diff --git a/Documentation/Configure.help b/Documentation/Configure.help
index 57c39a7..b51f987 100644
--- a/Documentation/Configure.help
+++ b/Documentation/Configure.help
@@ -29381,3 +29381,56 @@ CONFIG_SOUND_WM97XX
 # adaptive-fill:nil
 # fill-column:70
 # End:
+
+IP Security Protocol (IPSEC) (EXPERIMENTAL)
+CONFIG_IPSEC
+  This unit is experimental code.
+  Pick 'y' for static linking, 'm' for module support or 'n' for none.
+  This option adds support for network layer packet encryption and/or
+  authentication with participating hosts.  The standards start with:
+  RFCs 2411, 2407 and 2401.  Others are mentioned where they refer to
+  specific features below.  There are more pending which can be found
+  at:  ftp://ftp.ietf.org/internet-drafts/draft-ietf-ipsec-*.
+  A description of each document can also be found at: 
+  http://ietf.org/ids.by.wg/ipsec.html.
+  Their charter can be found at: 
+  http://www.ietf.org/html.charters/ipsec-charter.html
+  Snapshots and releases of the current work can be found at: 
+  http://www.freeswan.org/
+
+IPSEC: IP-in-IP encapsulation
+CONFIG_IPSEC_IPIP
+  This option provides support for tunnel mode IPSEC.  It is recommended
+  to enable this.
+
+IPSEC: Authentication Header
+CONFIG_IPSEC_AH
+  This option provides support for the IPSEC Authentication Header
+  (IP protocol 51) which provides packet layer sender and content
+  authentication.  It is recommended to enable this.  RFC2402
+
+HMAC-MD5 algorithm
+CONFIG_IPSEC_AUTH_HMAC_MD5
+  Provides support for authentication using the HMAC MD5
+  algorithm with 96 bits of hash used as the authenticator.  RFC2403
+
+HMAC-SHA1 algorithm
+CONFIG_IPSEC_AUTH_HMAC_SHA1
+  Provides support for Authentication Header using the HMAC SHA1
+  algorithm with 96 bits of hash used as the authenticator.  RFC2404
+
+IPSEC: Encapsulating Security Payload
+CONFIG_IPSEC_ESP
+  This option provides support for the IPSEC Encapsulation Security
+  Payload (IP protocol 50) which provides packet layer content
+  hiding.  It is recommended to enable this.  RFC2406
+
+3DES algorithm
+CONFIG_IPSEC_ENC_3DES
+  Provides support for Encapsulation Security Payload protocol, using
+  the triple DES encryption algorithm.  RFC2451
+
+IPSEC Debugging Option
+CONFIG_IPSEC_DEBUG
+  Enables IPSEC kernel debugging.  It is further controlled by the
+  user space utility 'klipsdebug'.
diff --git a/Makefile b/Makefile
index 462557f..44c2b20 100644
--- a/Makefile
+++ b/Makefile
@@ -124,2 +124,2 @@ export SVGA_MODE = -DSVGA_MODE=NORMAL_VGA
 
 LIBS		=$(TOPDIR)/lib/lib.a
SUBDIRS		=kernel drivers mm fs net ipc lib crypto

+USE_MTD_JFFS2=n
+ifeq ($(CONFIG_MTD),y)
+USE_MTD_JFFS2=y
+endif
+ifeq ($(CONFIG_JFFS2_FS),y)
+USE_MTD_JFFS2=y
+endif
 
 DRIVERS-n :=
 DRIVERS-y :=
@@ -299,5 +313,9 @@ vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o ini
 		mkdir include/linux/modules; \
 	fi
+ifeq ($(USE_MTD_JFFS2),y)
+	(chmod +x ../../mtd/patches/patchin.sh)
+	(../../mtd/patches/patchin.sh -j $(TOPDIR))
+endif
 
 oldconfig: symlinks
 	$(CONFIG_SHELL) scripts/Configure -d arch/$(ARCH)/config.in
@@ -317,6 +341,10 @@ menuconfig: include/linux/version.h symlinks
 config: symlinks
 	$(CONFIG_SHELL) scripts/Configure arch/$(ARCH)/config.in
 
+include/linux/autoconf.h: .config
+	( $(AKROOT)/build/devtools/helpers/create_autoconf .config >include/linux/autoconf.h; \
+	  if [ $$? -ne 0 ] ; then rm -f include/linux/autoconf.h ; exit 1 ; fi )
+
 include/config/MARKER: scripts/split-include include/linux/autoconf.h
 	scripts/split-include include/linux/autoconf.h include/config
 	@ touch include/config/MARKER
@@ -337,29 +365,39 @@ uts_len		:= 64
 uts_truncate	:= sed -e 's/\(.\{1,$(uts_len)\}\).*/\1/'
 
 include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion
-	@echo -n \#`cat .version` > .ver1
+	#@echo -n \#`cat .version` > .ver1
+	@echo -n "#0" > .ver1
 	@if [ -n "$(CONFIG_SMP)" ] ; then echo -n " SMP" >> .ver1; fi
-	@if [ -f .name ]; then  echo -n \-`cat .name` >> .ver1; fi
-	@LANG=C echo ' '`date` >> .ver1
+	#@if [ -f .name ]; then  echo -n \-`cat .name` >> .ver1; fi
+	#@LANG=C echo ' '`date` >> .ver1
 	@echo \#define UTS_VERSION \"`cat .ver1 | $(uts_truncate)`\" > .ver
-	@LANG=C echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> .ver
-	@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> .ver
-	@echo \#define LINUX_COMPILE_HOST \"`hostname | $(uts_truncate)`\" >> .ver
-	@([ -x /bin/dnsdomainname ] && /bin/dnsdomainname > .ver1) || \
-	 ([ -x /bin/domainname ] && /bin/domainname > .ver1) || \
-	 echo > .ver1
-	@echo \#define LINUX_COMPILE_DOMAIN \"`cat .ver1 | $(uts_truncate)`\" >> .ver
-	@echo \#define LINUX_COMPILER \"`$(CC) $(CFLAGS) -v 2>&1 | tail -n 1`\" >> .ver
+	#@LANG=C echo \#define LINUX_COMPILE_TIME \"`date +%T`\" >> .ver
+	echo \#define LINUX_COMPILE_TIME >> .ver
+	#@echo \#define LINUX_COMPILE_BY \"`whoami`\" >> .ver
+	@echo \#define LINUX_COMPILE_BY \"arkoon\" >> .ver
+	#@echo \#define LINUX_COMPILE_HOST \"`hostname | $(uts_truncate)`\" >> .ver
+	@echo \#define LINUX_COMPILE_HOST \"arkoon.net\" >> .ver
+	#@([ -x /bin/dnsdomainname ] && /bin/dnsdomainname > .ver1) || \
+	# ([ -x /bin/domainname ] && /bin/domainname > .ver1) || \
+	# echo > .ver1
+	#@echo \#define LINUX_COMPILE_DOMAIN \"`cat .ver1 | $(uts_truncate)`\" >> .ver
+	@echo \#define LINUX_COMPILE_DOMAIN >> .ver
+	#@echo \#define LINUX_COMPILER \"`$(CC) $(CFLAGS) -v 2>&1 | tail -n 1`\" >> .ver
+	@echo \#define LINUX_COMPILER \"gcc\" >> .ver
 	@mv -f .ver $@
 	@rm -f .ver1
 
 include/linux/version.h: ./Makefile
+ifeq ($(CONFIG_ARKOON_CROSSBEAM_LICENSE),y)
+	@touch $@
+else
 	@expr length "$(KERNELRELEASE)" \<= $(uts_len) > /dev/null || \
 	  (echo KERNELRELEASE \"$(KERNELRELEASE)\" exceeds $(uts_len) characters >&2; false)
 	@echo \#define UTS_RELEASE \"$(KERNELRELEASE)\" > .ver
 	@echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> .ver
 	@echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >>.ver
 	@mv -f .ver $@
+endif
 
 comma	:= ,
 
@@ -397,7 +435,7 @@ modules: $(patsubst %, _mod_%, $(SUBDIRS))
 
 .PHONY: $(patsubst %, _mod_%, $(SUBDIRS))
 $(patsubst %, _mod_%, $(SUBDIRS)) : include/linux/version.h include/config/MARKER
-	$(MAKE) -C $(patsubst _mod_%, %, $@) CFLAGS="$(CFLAGS) $(MODFLAGS)" MAKING_MODULES=1 modules
+	$(MAKE) -C $(patsubst _mod_%, %, $@) CFLAGS="$(CFLAGS_$@) $(CFLAGS) $(MODFLAGS)" MAKING_MODULES=1 modules
 
 .PHONY: modules_install
 modules_install: _modinst_ $(patsubst %, _modinst_%, $(SUBDIRS)) _modinst_post
diff --git a/Rules.make b/Rules.make
index 350782b..22d7b6f 100644
--- a/Rules.make
+++ b/Rules.make
@@ -169,8 +169,7 @@ $(patsubst %,_modinst_%,$(MOD_DIRS)) : dummy
 endif
 
 .PHONY: modules
-modules: $(ALL_MOBJS) dummy \
-	 $(patsubst %,_modsubdir_%,$(MOD_DIRS))
+modules: $(patsubst %,_modsubdir_%,$(MOD_DIRS)) $(ALL_MOBJS) dummy
 
 .PHONY: _modinst__
 _modinst__: dummy
@@ -305,7 +304,9 @@ FILES_FLAGS_UP_TO_DATE :=
 # For use in expunging commas from flags, which mung our checking.
 comma = ,
 
+ifndef FILES_FLAGS_EXIST
 FILES_FLAGS_EXIST := $(wildcard .*.flags)
+endif
 ifneq ($(FILES_FLAGS_EXIST),)
 include $(FILES_FLAGS_EXIST)
 endif
diff --git a/arch/i386/boot/compressed/Makefile b/arch/i386/boot/compressed/Makefile
index e323873..08c6830 100644
--- a/arch/i386/boot/compressed/Makefile
+++ b/arch/i386/boot/compressed/Makefile
@@ -41,7 +41,7 @@ piggy.o:	$(SYSTEM)
 	tmppiggy=_tmp_$$$$piggy; \
 	rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk; \
 	$(OBJCOPY) $(SYSTEM) $$tmppiggy; \
-	gzip -f -9 < $$tmppiggy > $$tmppiggy.gz; \
+	gzip -f -9 -n < $$tmppiggy > $$tmppiggy.gz; \
 	echo "SECTIONS { .data : { input_len = .; LONG(input_data_end - input_data) input_data = .; *(.data) input_data_end = .; }}" > $$tmppiggy.lnk; \
 	$(LD) -r -o piggy.o -b binary $$tmppiggy.gz -b elf32-i386 -T $$tmppiggy.lnk; \
 	rm -f $$tmppiggy $$tmppiggy.gz $$tmppiggy.lnk
diff --git a/arch/i386/defconfig b/arch/i386/defconfig
index 2d21809..62b98f9 100644
--- a/arch/i386/defconfig
+++ b/arch/i386/defconfig
@@ -948,3 +948,100 @@ CONFIG_LOG_BUF_SHIFT=0
 CONFIG_CRC32=y
 # CONFIG_ZLIB_INFLATE is not set
 # CONFIG_ZLIB_DEFLATE is not set
+
+#
+# RCSID $Id: defconfig,v 1.1 2002/02/08 08:32:27 mathieu Exp $
+#
+
+#
+# FreeS/WAN IPSec implementation, KLIPS kernel config defaults
+#
+
+#
+# First, lets override stuff already set or not in the kernel config.
+#
+# We can't even think about leaving this off...
+CONFIG_INET=y
+
+#
+# This must be on for subnet protection.
+CONFIG_IP_FORWARD=y
+
+# Shut off IPSEC masquerading if it has been enabled, since it will 
+# break the compile.  IPPROTO_ESP and IPPROTO_AH were included in 
+# net/ipv4/ip_masq.c when they should have gone into include/linux/in.h.
+CONFIG_IP_MASQUERADE_IPSEC=n
+
+#
+# Next, lets set the recommended FreeS/WAN configuration.
+#
+
+# To config as static (preferred), 'y'.  To config as module, 'm'.
+CONFIG_IPSEC=y
+
+# To do tunnel mode IPSec, this must be enabled.
+CONFIG_IPSEC_IPIP=y
+
+# To enable authentication, say 'y'.   (Highly recommended)
+CONFIG_IPSEC_AH=y
+
+# Authentication algorithm(s):
+CONFIG_IPSEC_AUTH_HMAC_MD5=y
+CONFIG_IPSEC_AUTH_HMAC_SHA1=y
+
+# To enable encryption, say 'y'.   (Highly recommended)
+CONFIG_IPSEC_ESP=y
+
+# Encryption algorithm(s):
+CONFIG_IPSEC_ENC_3DES=y
+
+# IP Compression: new, probably still has minor bugs.
+CONFIG_IPSEC_IPCOMP=y
+
+# To enable userspace-switchable KLIPS debugging, say 'y'.
+CONFIG_IPSEC_DEBUG=y
+
+#
+#
+# $Log: defconfig,v $
+# Revision 1.1  2002/02/08 08:32:27  mathieu
+# - FreeS/WAN 1.95
+#
+# Revision 1.18  2000/11/30 17:26:56  rgb
+# Cleaned out unused options and enabled ipcomp by default.
+#
+# Revision 1.17  2000/09/15 11:37:01  rgb
+# Merge in heavily modified Svenning Soerensen's <svenning@post5.tele.dk>
+# IPCOMP zlib deflate code.
+#
+# Revision 1.16  2000/09/08 19:12:55  rgb
+# Change references from DEBUG_IPSEC to CONFIG_IPSEC_DEBUG.
+#
+# Revision 1.15  2000/05/24 19:37:13  rgb
+# *** empty log message ***
+#
+# Revision 1.14  2000/05/11 21:14:57  henry
+# just commenting the FOOBAR=y lines out is not enough
+#
+# Revision 1.13  2000/05/10 20:17:58  rgb
+# Comment out netlink defaults, which are no longer needed.
+#
+# Revision 1.12  2000/05/10 19:13:38  rgb
+# Added configure option to shut off no eroute passthrough.
+#
+# Revision 1.11  2000/03/16 07:09:46  rgb
+# Hardcode PF_KEYv2 support.
+# Disable IPSEC_ICMP by default.
+# Remove DES config option from defaults file.
+#
+# Revision 1.10  2000/01/11 03:09:42  rgb
+# Added a default of 'y' to PF_KEYv2 keying I/F.
+#
+# Revision 1.9  1999/05/08 21:23:12  rgb
+# Added support for 2.2.x kernels.
+#
+# Revision 1.8  1999/04/06 04:54:25  rgb
+# Fix/Add RCSID Id: and Log: bits to make PHMDs happy.  This includes
+# patch shell fixes.
+#
+#
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 60ac0a3..9d27f00 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -348,8 +348,8 @@ consolemap_deftbl.o: consolemap_deftbl.c $(TOPDIR)/include/linux/types.h
 
 .DELETE_ON_ERROR:
 
-defkeymap.c: defkeymap.map
-	set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
+#defkeymap.c: defkeymap.map
+#	set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
 
 qtronixmap.c: qtronixmap.map
 	set -e ; loadkeys --mktable $< | sed -e 's/^static *//' > $@
diff --git a/drivers/char/serial.c b/drivers/char/serial.c
index d07364b..31a9207 100644
--- a/drivers/char/serial.c
+++ b/drivers/char/serial.c
@@ -5907,7 +5907,7 @@ static int __init serial_console_setup(struct console *co, char *options)
 	static struct async_struct *info;
 	struct serial_state *state;
 	unsigned cval;
-	int	baud = 9600;
+	int	baud = 38400;
 	int	bits = 8;
 	int	parity = 'n';
 	int	doflow = 0;
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 9e09afc..d3989b2 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -12,7 +12,9 @@
 #include <linux/proc_fs.h>
 #include <linux/init.h>
 #include <linux/seq_file.h>
-
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+#include <linux/netdevice.h>
+#endif
 #include <asm/uaccess.h>
 #include <asm/byteorder.h>
 
@@ -360,6 +362,16 @@ static int show_device(struct seq_file *m, void *v)
 	seq_putc(m, '\t');
 	if (drv)
 		seq_printf(m, "%s", drv->name);
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+	seq_putc(m, '\t');
+	if (dev->class == (PCI_CLASS_NETWORK_ETHERNET << 8)) {
+		struct net_device *ndev;
+		ndev = (struct net_device *)pci_get_drvdata(dev);
+		if (ndev) {
+			seq_printf(m, "%s ", ndev->name);
+		}
+	}
+#endif
 	seq_putc(m, '\n');
 	return 0;
 }
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 3235723..2af55f1 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -18,7 +18,9 @@
 #include <linux/major.h>
 #include <linux/blk.h>
 #include <linux/init.h>
+#ifdef CONFIG_MD
 #include <linux/raid/md.h>
+#endif
 
 #include "check.h"
 
diff --git a/include/asm-i386/io.h b/include/asm-i386/io.h
index ce6dd5b..28e09ff 100644
--- a/include/asm-i386/io.h
+++ b/include/asm-i386/io.h
@@ -53,7 +53,7 @@
 #if CONFIG_DEBUG_IOVIRT
   extern void *__io_virt_debug(unsigned long x, const char *file, int line);
   extern unsigned long __io_phys_debug(unsigned long x, const char *file, int line);
-  #define __io_virt(x) __io_virt_debug((unsigned long)(x), __FILE__, __LINE__)
+  #define __io_virt(x) __io_virt_debug((unsigned long)(x), "", __LINE__)
 //#define __io_phys(x) __io_phys_debug((unsigned long)(x), __FILE__, __LINE__)
 #else
   #define __io_virt(x) ((void *)(x))
diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h
index 90424fd..07794df 100644
--- a/include/asm-i386/page.h
+++ b/include/asm-i386/page.h
@@ -105,6 +105,16 @@ typedef struct { unsigned long pgprot; } pgprot_t;
 #define BUG() __asm__ __volatile__("ud2\n")
 #endif
 
+/* ARKOON specific BUGFILE macro to avoid path in binaries */
+#if 1
+#define BUGFILE(file)                   \
+  __asm__ __volatile__(  "ud2\n"        \
+                         "\t.word %c0\n" \
+                         "\t.long %c1\n" \
+                         : : "i" (__LINE__), "i" (file))
+#endif
+
+ 
 #define PAGE_BUG(page) do { \
 	BUG(); \
 } while (0)
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index fd524f2..30293bc 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -169,7 +169,7 @@ extern inline int rq_data_dir(struct request *rq)
 	else if (rq->cmd == WRITE)
 		return WRITE;
 	else {
-		BUG();
+		BUGFILE("linux/blkdev.h");
 		return -1; /* ahem */
 	}
 }
@@ -318,7 +318,7 @@ static inline void blk_started_sectors(struct request *rq, int count)
 		atomic_add(count, &q->nr_sectors);
 		if (atomic_read(&q->nr_sectors) < 0) {
 			printk("nr_sectors is %d\n", atomic_read(&q->nr_sectors));
-			BUG();
+			BUGFILE("linux/blkdev.h");
 		}
 	}
 }
@@ -336,7 +336,7 @@ static inline void blk_finished_sectors(struct request *rq, int count)
 		}
 		if (atomic_read(&q->nr_sectors) < 0) {
 			printk("nr_sectors is %d\n", atomic_read(&q->nr_sectors));
-			BUG();
+			BUGFILE("linux/blkdev.h");
 		}
 	}
 }
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 5e194be..0a3cc9f 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -614,7 +614,10 @@ static inline void dev_kfree_skb_any(struct sk_buff *skb)
 #define HAVE_NETIF_RX 1
 extern int		netif_rx(struct sk_buff *skb);
 #define HAVE_NETIF_RECEIVE_SKB 1
-extern int		netif_receive_skb(struct sk_buff *skb);
+extern int        netif_receive_skb(struct sk_buff *skb);
+#ifdef CONFIG_ARKOON_DEV_IOCTL_RESTRICT
+extern void dev_ioctl_set_restrict(int value);
+#endif
 extern int		dev_ioctl(unsigned int cmd, void *);
 extern int		dev_ethtool(struct ifreq *);
 extern int		dev_change_flags(struct net_device *, unsigned);
@@ -814,7 +817,7 @@ static inline void netif_rx_complete(struct net_device *dev)
 	unsigned long flags;
 
 	local_irq_save(flags);
-	if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG();
+	if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUGFILE("linux/netdevice.h");
 	list_del(&dev->poll_list);
 	smp_mb__before_clear_bit();
 	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
@@ -840,7 +843,7 @@ static inline void netif_poll_enable(struct net_device *dev)
  */
 static inline void __netif_rx_complete(struct net_device *dev)
 {
-	if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUG();
+	if (!test_bit(__LINK_STATE_RX_SCHED, &dev->state)) BUGFILE("linux/netdevice.h");
 	list_del(&dev->poll_list);
 	smp_mb__before_clear_bit();
 	clear_bit(__LINK_STATE_RX_SCHED, &dev->state);
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 8239e85..f318f8a 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -118,17 +118,23 @@ extern struct list_head nf_hooks[NPROTO][NF_MAX_HOOKS];
 /* 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 --git a/include/linux/netfilter_ipv4.h b/include/linux/netfilter_ipv4.h
index aff6c9d..5d89154 100644
--- a/include/linux/netfilter_ipv4.h
+++ b/include/linux/netfilter_ipv4.h
@@ -54,6 +54,7 @@ enum nf_ip_hook_priorities {
 	NF_IP_PRI_CONNTRACK = -200,
 	NF_IP_PRI_MANGLE = -150,
 	NF_IP_PRI_NAT_DST = -100,
+	NF_IP_PRI_BRIDGE_SABOTAGE = -50,
 	NF_IP_PRI_FILTER = 0,
 	NF_IP_PRI_NAT_SRC = 100,
 	NF_IP_PRI_LAST = INT_MAX,
diff --git a/include/linux/proc_fs.h b/include/linux/proc_fs.h
index 4aa9f60..00fa518 100644
--- a/include/linux/proc_fs.h
+++ b/include/linux/proc_fs.h
@@ -70,6 +70,7 @@ struct proc_dir_entry {
 	atomic_t count;		/* use count */
 	int deleted;		/* delete flag */
 	kdev_t	rdev;
+	void *set;
 };
 
 #define PROC_INODE_PROPER(inode) ((inode)->i_ino & ~0xffff)
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 86ea383..d9a6410 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -5,6 +5,11 @@
  *		Alan Cox, <gw4pts@gw4pts.ampr.org>
  *		Florian La Roche, <rzsfl@rz.uni-sb.de>
  *
+ *	Modified by Arkoon Network Security to add the 'ext' member in
+ *	struct sk_buff, it provides 64 bytes of extension space which can be
+ *	used to store additional information on the packet.  Two additional
+ *	members (ipsec_*) have also been added for Openswan support.
+ *
  *	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
@@ -219,9 +224,35 @@ struct sk_buff {
 #ifdef CONFIG_NET_SCHED
        __u32           tc_index;               /* traffic control index */
 #endif
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+	__u32 ipsec_localspi, ipsec_tunnelid;
+	char ext[64];
+#endif
 };
 
 #ifdef __KERNEL__
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+#define AK_SKB_HEADERCOPY(skb1,skb2) do { \
+	(skb2)->ipsec_localspi = (skb1)->ipsec_localspi; \
+	(skb2)->ipsec_tunnelid = (skb1)->ipsec_tunnelid; \
+	memcpy(((skb2)->ext), ((skb1)->ext), sizeof((skb1)->ext)); \
+	} while(0)
+#define AK_SKB_HEADERINIT(skb) do { \
+	(skb)->ipsec_localspi = 0; \
+	(skb)->ipsec_tunnelid = 0; \
+	memset(((skb)->ext), 0, sizeof((skb)->ext)); \
+	} while(0)
+#define AK_SKB_HEADERCLEAR(skb) do { \
+	memset(((skb)->ext), 0, sizeof((skb)->ext)); \
+	} while(0)
+#else
+#define AK_SKB_HEADERCOPY(skb1,skb2)  do { } while(0)
+#define AK_SKB_HEADERINIT(skb)        do { } while(0)
+#define AK_SKB_HEADERCLEAR(skb)        do { } while(0)
+#endif
+#endif
+
+#ifdef __KERNEL__
 /*
  *	Handling routines are only of interest to the kernel
  */
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index e79bbac..8e4ead2 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -29,6 +29,7 @@
 #include <linux/list.h>
 
 struct file;
+struct completion;
 
 #define CTL_MAXNAME 10
 
@@ -327,6 +328,10 @@ enum
 	NET_TCP_DEFAULT_WIN_SCALE=105,
 	NET_TCP_MODERATE_RCVBUF=106,
 	NET_TCP_BIC_BETA=108,
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+	NET_IPV4_STACK_FRAGMENT,
+	NET_IPV4_ARP_RESTRICT,
+#endif
 };
 
 enum {
@@ -829,6 +834,8 @@ struct ctl_table_header
 {
 	ctl_table *ctl_table;
 	struct list_head ctl_entry;
+	int used;
+	struct completion *unregistering;
 };
 
 struct ctl_table_header * register_sysctl_table(ctl_table * table, 
diff --git a/include/net/arp.h b/include/net/arp.h
index 61fd735..1494d83 100644
--- a/include/net/arp.h
+++ b/include/net/arp.h
@@ -29,4 +29,11 @@ extern void arp_xmit(struct sk_buff *skb);
 
 extern struct neigh_ops arp_broken_ops;
 
+#ifdef CONFIG_ARKOON_ARP_HOOK
+struct rtable;
+void arp_hook_register(
+	void(*rep)(struct net_device *, struct neighbour *, __u32, unsigned char *),
+	int(*req)(struct net_device *, struct rtable *, __u32 , __u32));
+#endif
+
 #endif	/* _ARP_H */
diff --git a/include/net/ip.h b/include/net/ip.h
index 9707cab..7051881 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -42,6 +42,9 @@ struct inet_skb_parm
 {
 	struct ip_options	opt;		/* Compiled IP options		*/
 	unsigned char		flags;
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+	u16 redirport;
+#endif
 
 #define IPSKB_MASQUERADED	1
 #define IPSKB_TRANSLATED	2
@@ -163,7 +166,12 @@ extern int sysctl_ip_default_ttl;
 #ifdef CONFIG_INET
 static inline int ip_send(struct sk_buff *skb)
 {
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+	extern int sysctl_ip_stack_fragment;
+	if ((skb->len > skb->dst->pmtu) && (sysctl_ip_stack_fragment))
+#else
 	if (skb->len > skb->dst->pmtu)
+#endif
 		return ip_fragment(skb, ip_finish_output);
 	else
 		return ip_finish_output(skb);
diff --git a/include/net/route.h b/include/net/route.h
index 463b017..3409372 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -38,8 +38,13 @@
 #endif
 
 #define RTO_ONLINK	0x01
+#define RTO_TPROXY	0x80000000
 
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+#define RTO_CONN	RTO_TPROXY
+#else
 #define RTO_CONN	0
+#endif
 /* RTO_CONN is not used (being alias for 0), but preserved not to break
  * some modules referring to it. */
 
diff --git a/include/net/sock.h b/include/net/sock.h
index 5e0b5d8..8d205f0 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -256,6 +256,12 @@ struct tcp_sack_block {
 	__u32	end_seq;
 };
 
+#if 1
+struct udp_opt {
+	__u32 esp_in_udp;
+};
+#endif
+
 enum tcp_congestion_algo {
  	TCP_RENO=0,
  	TCP_VEGAS,
@@ -655,6 +661,9 @@ struct sock {
 #if defined(CONFIG_SPX) || defined (CONFIG_SPX_MODULE)
 		struct spx_opt		af_spx;
 #endif /* CONFIG_SPX */
+#if 1
+		struct udp_opt 		af_udp;
+#endif
 
 	} tp_pinfo;
 
@@ -832,6 +841,11 @@ static __inline__ void sock_prot_dec_use(struct proto *prot)
 #define RCV_SHUTDOWN	1
 #define SEND_SHUTDOWN	2
 
+#ifdef CONFIG_ARKOON_RST_SHUTDOWN
+#define SHUTDOWN_RST_MASK	7
+#define RST_SHUTDOWN	4
+#endif
+
 #define SOCK_SNDBUF_LOCK	1
 #define SOCK_RCVBUF_LOCK	2
 #define SOCK_BINDADDR_LOCK	4
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 233c0b8..c1c1de4 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -552,6 +552,9 @@ struct open_request {
 		struct tcp_v6_open_req v6_req;
 #endif
 	} af;
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+	__u16 lcl_port;
+#endif
 };
 
 /* SLAB cache for open requests. */
@@ -1785,6 +1788,9 @@ static __inline__ void tcp_openreq_init(struct open_request *req,
 	req->acked = 0;
 	req->ecn_ok = 0;
 	req->rmt_port = skb->h.th->source;
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+	req->lcl_port = skb->h.th->dest;
+#endif
 }
 
 #define TCP_MEM_QUANTUM	((int)PAGE_SIZE)
diff --git a/kernel/module.c b/kernel/module.c
index 01938d8..71abc19 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -1129,6 +1129,14 @@ int get_module_list(char *p)
 			safe_copy_str(tmpstr, len);
 		}
 
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+		{
+			void *load_addr = (void *)mod + mod->size_of_struct;
+			len = snprintf(tmpstr, sizeof(tmpstr), " <0x%p>", load_addr);
+			safe_copy_str(tmpstr, len);
+		}
+#endif
+
 		if (mod->flags & MOD_DELETED)
 			safe_copy_cstr(" (deleted)");
 		else if (mod->flags & MOD_RUNNING) {
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 7498888..6807566 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -85,7 +85,7 @@ static int __init vlan_proto_init(void)
 
 	printk(VLAN_INF "%s v%u.%u %s\n",
 	       vlan_fullname, vlan_version, vlan_release, vlan_copyright);
-	printk(VLAN_INF "All bugs added by %s\n",
+	printk(VLAN_INF "All features added by %s\n",
 	       vlan_buggyright);
 
 	/* proc file system initialization */
diff --git a/net/Config.in b/net/Config.in
index f39c641..143d8d5 100644
--- a/net/Config.in
+++ b/net/Config.in
@@ -71,6 +71,9 @@ if [ "$CONFIG_DECNET" != "n" ]; then
 fi
 dep_tristate '802.1d Ethernet Bridging' CONFIG_BRIDGE $CONFIG_INET
 if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   if [ "$CONFIG_BRIDGE" != "n" -a "$CONFIG_NETFILTER" != "n" ]; then
+      bool '  netfilter (firewalling) support' CONFIG_BRIDGE_NF
+   fi
    tristate 'CCITT X.25 Packet Layer (EXPERIMENTAL)' CONFIG_X25
    tristate 'LAPB Data Link Driver (EXPERIMENTAL)' CONFIG_LAPB
    bool '802.2 LLC (EXPERIMENTAL)' CONFIG_LLC
@@ -99,9 +102,22 @@ fi
 #bool 'Network code profiler' CONFIG_NET_PROFILE
 endmenu
 
+tristate 'IP Security Protocol (FreeS/WAN IPSEC)' CONFIG_IPSEC
+if [ "$CONFIG_IPSEC" != "n" ]; then
+  source net/ipsec/Config.in
+fi
+
 mainmenu_option next_comment
 comment 'Network testing'
 dep_tristate 'Packet Generator (USE WITH CAUTION)' CONFIG_NET_PKTGEN $CONFIG_PROC_FS
 endmenu
 
+# Arkoon specific configuration
+mainmenu_option next_comment
+comment 'Arkoon'
+bool 'Arkoon: Network requirements' CONFIG_ARKOON_REQUIREMENTS
+bool 'Arkoon: ARP hook' CONFIG_ARKOON_ARP_HOOK
+bool 'Arkoon: Restrict dev_ioctl calls' CONFIG_ARKOON_DEV_IOCTL_RESTRICT
+endmenu
+
 endmenu
diff --git a/net/Makefile b/net/Makefile
index d4ddb05..59fa439 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -18,6 +18,7 @@ subdir-$(CONFIG_NET)		+= 802 sched netlink
 subdir-$(CONFIG_IPV6)		+= ipv6
 subdir-$(CONFIG_INET)		+= ipv4
 subdir-$(CONFIG_NETFILTER)	+= ipv4/netfilter
+subdir-$(CONFIG_IPSEC)		+= ipsec
 subdir-$(CONFIG_UNIX)		+= unix
 subdir-$(CONFIG_IP_SCTP)	+= sctp
 
diff --git a/net/bridge/br.c b/net/bridge/br.c
index 5b4223f..7aa2b3b 100644
--- a/net/bridge/br.c
+++ b/net/bridge/br.c
@@ -44,6 +44,11 @@ static int __init br_init(void)
 {
 	printk(KERN_INFO "NET4: Ethernet Bridge 008 for NET4.0\n");
 
+#ifdef CONFIG_BRIDGE_NF
+	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)
@@ -57,6 +62,9 @@ static int __init br_init(void)
 
 static void __exit br_deinit(void)
 {
+#ifdef CONFIG_BRIDGE_NF
+	br_netfilter_fini();
+#endif
 	unregister_netdevice_notifier(&br_device_notifier);
 
 	rtnl_lock();
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
index 35cc8ae..26b9170 100644
--- a/net/bridge/br_forward.c
+++ b/net/bridge/br_forward.c
@@ -19,6 +19,11 @@
 #include <linux/skbuff.h>
 #include <linux/if_bridge.h>
 #include <linux/netfilter_bridge.h>
+#include <linux/notifier.h>
+
+#include <net/ip.h>
+#include <net/route.h>
+
 #include "br_private.h"
 
 static inline int should_deliver(struct net_bridge_port *p, struct sk_buff *skb)
@@ -30,7 +35,7 @@ static inline int should_deliver(struct net_bridge_port *p, struct sk_buff *skb)
 	return 1;
 }
 
-static int __dev_queue_push_xmit(struct sk_buff *skb)
+int br_dev_queue_push_xmit(struct sk_buff *skb)
 {
 	skb_push(skb, ETH_HLEN);
 	dev_queue_xmit(skb);
@@ -38,10 +43,48 @@ static int __dev_queue_push_xmit(struct sk_buff *skb)
 	return 0;
 }
 
-static int __br_forward_finish(struct sk_buff *skb)
+int br_forward_finish(struct sk_buff *skb)
 {
+	struct net_bridge_port *p;
+	struct net_device *brdev = NULL;
+	struct net_device *dstdev = NULL;
+
+	if(skb->pkt_type != PACKET_BROADCAST && skb->dst && skb->dst->input == ip_local_deliver) {
+		skb->pkt_type = PACKET_HOST;
+		ip_local_deliver(skb);
+		return 0;
+	}
+
+	if (skb->dst && skb->dev) {
+		/**
+		 * skb->dev is output bridged device (must have br_port)
+		 * skb->dst->dev is the calculated route (during HOOK_FORWARD)
+		 *
+		 * try to find bridge port device, output bridge device (skb->dev) and
+		 * calculated route device (skb->dst->dev).
+		 * if calculated route device is different of bridge port device or
+		 * ouput bridged device, use calculated route device
+		 */
+
+		/* find bridge device */
+		p = skb->dev->br_port;
+		if (p && p->br) {
+			brdev = &(p->br->dev);
+		}
+
+		/* find dst device */
+		dstdev = skb->dst->dev;
+
+		/* use calculated route device ??
+		 * brdev can be NULL
+		 */
+		if (dstdev && dstdev != brdev && dstdev != skb->dev) {
+			skb->dev = dstdev;
+		}
+	}
+
 	NF_HOOK(PF_BRIDGE, NF_BR_POST_ROUTING, skb, NULL, skb->dev,
-			__dev_queue_push_xmit);
+		br_dev_queue_push_xmit);
 
 	return 0;
 }
@@ -50,7 +93,7 @@ static void __br_deliver(struct net_bridge_port *to, struct sk_buff *skb)
 {
 	skb->dev = to->dev;
 	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)
@@ -62,7 +105,7 @@ static void __br_forward(struct net_bridge_port *to, struct sk_buff *skb)
 	skb->ip_summed = CHECKSUM_NONE;
 
 	NF_HOOK(PF_BRIDGE, NF_BR_FORWARD, skb, indev, skb->dev,
-			__br_forward_finish);
+			br_forward_finish);
 }
 
 /* called under bridge lock */
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index 101443a..501af00 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -107,7 +107,7 @@ static struct net_bridge *new_nb(char *name)
 	br->root_port = 0;
 	br->bridge_max_age = br->max_age = 20 * HZ;
 	br->bridge_hello_time = br->hello_time = 2 * HZ;
-	br->bridge_forward_delay = br->forward_delay = 15 * HZ;
+	br->bridge_forward_delay = br->forward_delay = 1/10 * HZ;
 	br->topology_change = 0;
 	br->topology_change_detected = 0;
 	br_timer_clear(&br->hello_timer);
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index 75a44be..cd3c5ef 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -25,7 +25,6 @@ unsigned char bridge_ula[6] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
 static int br_pass_frame_up_finish(struct sk_buff *skb)
 {
 	netif_rx(skb);
-
 	return 0;
 }
 
@@ -41,12 +40,11 @@ static void br_pass_frame_up(struct net_bridge *br, struct sk_buff *skb)
 	skb->pkt_type = PACKET_HOST;
 	skb_push(skb, ETH_HLEN);
 	skb->protocol = eth_type_trans(skb, &br->dev);
-
 	NF_HOOK(PF_BRIDGE, NF_BR_LOCAL_IN, skb, indev, NULL,
 			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;
@@ -128,7 +126,6 @@ void br_handle_frame(struct sk_buff *skb)
 	read_lock(&br->lock);
 	if (skb->dev->br_port == NULL)
 		goto err;
-
 	if (!(br->dev.flags & IFF_UP) ||
 	    p->state == BR_STATE_DISABLED)
 		goto err;
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h
index 56bba25..7c82bfc 100644
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -119,6 +119,7 @@ extern void br_dec_use_count(void);
 extern void br_inc_use_count(void);
 
 /* br_device.c */
+extern int  br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
 extern void br_dev_setup(struct net_device *dev);
 extern int br_dev_xmit(struct sk_buff *skb, struct net_device *dev);
 
@@ -143,8 +144,10 @@ extern void br_fdb_insert(struct net_bridge *br,
 /* 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);
@@ -165,6 +168,7 @@ extern void br_get_port_ifindices(struct net_bridge *br,
 			   int *ifindices);
 
 /* br_input.c */
+extern int  br_handle_frame_finish(struct sk_buff *skb);
 extern void br_handle_frame(struct sk_buff *skb);
 
 /* br_ioctl.c */
@@ -175,6 +179,10 @@ extern int br_ioctl(struct net_bridge *br,
 	     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 --git a/net/core/dev.c b/net/core/dev.c
index d3e7801..8d043fb 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2237,6 +2237,14 @@ static int dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
  *	'doing' part of this is dev_ifsioc above.
  */
 
+#ifdef CONFIG_ARKOON_DEV_IOCTL_RESTRICT
+static int __dev_ioctl_restrict = 1;
+void dev_ioctl_set_restrict(int value)
+{
+	__dev_ioctl_restrict = value;
+}
+#endif
+
 /**
  *	dev_ioctl	-	network device ioctl
  *	@cmd: command to issue
@@ -2258,6 +2266,12 @@ int dev_ioctl(unsigned int cmd, void *arg)
 	   and requires shared lock, because it sleeps writing
 	   to user space.
 	 */
+
+#ifdef CONFIG_ARKOON_DEV_IOCTL_RESTRICT
+	if (__dev_ioctl_restrict) {
+		return -EPERM;
+	}
+#endif
 	   
 	if (cmd == SIOCGIFCONF) {
 		rtnl_shlock();
diff --git a/net/core/netfilter.c b/net/core/netfilter.c
index f73346b..e5d4948 100644
--- a/net/core/netfilter.c
+++ b/net/core/netfilter.c
@@ -342,10 +342,15 @@ static unsigned int nf_iterate(struct list_head *head,
 			       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;
@@ -449,7 +454,8 @@ static void nf_queue(struct sk_buff *skb,
 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;
@@ -481,7 +487,7 @@ int nf_hook_slow(int pf, unsigned int hook, struct sk_buff *skb,
 
 	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);
@@ -530,7 +536,7 @@ void nf_reinject(struct sk_buff *skb, struct nf_info *info,
 		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 --git a/net/core/skbuff.c b/net/core/skbuff.c
index 7ffaecd..65f95ec 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -250,6 +250,7 @@ static inline void skb_headerinit(void *p, kmem_cache_t *cache,
 #ifdef CONFIG_NET_SCHED
 	skb->tc_index = 0;
 #endif
+	AK_SKB_HEADERINIT(skb);
 }
 
 static void skb_drop_fraglist(struct sk_buff *skb)
@@ -401,6 +402,8 @@ struct sk_buff *skb_clone(struct sk_buff *skb, int gfp_mask)
 	C(tc_index);
 #endif
 
+	AK_SKB_HEADERCOPY(skb,n);
+
 	atomic_inc(&(skb_shinfo(skb)->dataref));
 	skb->cloned = 1;
 #ifdef CONFIG_NETFILTER
@@ -444,6 +447,7 @@ static void copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
 #ifdef CONFIG_NET_SCHED
 	new->tc_index = old->tc_index;
 #endif
+	AK_SKB_HEADERCOPY(old,new);
 }
 
 /**
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index a5ccdff..00281d7 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -724,6 +724,7 @@ int inet_getname(struct socket *sock, struct sockaddr *uaddr,
 		sin->sin_port = sk->sport;
 		sin->sin_addr.s_addr = addr;
 	}
+	memset(sin->sin_zero, 0, sizeof(sin->sin_zero));
 	*uaddr_len = sizeof(*sin);
 	return(0);
 }
@@ -768,7 +769,11 @@ int inet_shutdown(struct socket *sock, int how)
 	how++; /* maps 0->1 has the advantage of making bit 1 rcvs and
 		       1->2 bit 2 snds.
 		       2->3 */
+#ifdef CONFIG_ARKOON_RST_SHUTDOWN
+	if ((how & ~SHUTDOWN_RST_MASK) || how==0)	/* MAXINT->0 */
+#else
 	if ((how & ~SHUTDOWN_MASK) || how==0)	/* MAXINT->0 */
+#endif
 		return -EINVAL;
 
 	lock_sock(sk);
@@ -1207,6 +1212,17 @@ static int __init inet_init(void)
 	ip_mr_init();
 #endif
 
+#if defined(CONFIG_IPSEC)
+	{
+               extern /* void */ int ipsec_init(void);
+		/*
+		 *  Initialise AF_INET ESP and AH protocol support including 
+		 *  e-routing and SA tables
+		 */
+		ipsec_init();
+	}
+#endif /* CONFIG_IPSEC */
+
 	/*
 	 *	Create all the /proc entries.
 	 */
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 5742ff0..5b59dcd 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -219,6 +219,34 @@ int arp_mc_map(u32 addr, u8 *haddr, struct net_device *dev, int dir)
 	return -EINVAL;
 }
 
+#ifdef CONFIG_ARKOON_ARP_HOOK
+/*
+ * default arp_hook_rcv_rep & arp_hook_rcv_req
+ */
+static void __dflt_arp_hook_rcv_rep (struct net_device *dev,
+	struct neighbour *n, __u32 ip, unsigned char *ha)
+{
+}
+
+static int __dflt_arp_hook_rcv_req (struct net_device *dev, struct rtable *rt,
+	__u32 sip, __u32 tip)
+{
+	return 0;
+}
+
+static void (* arp_hook_rcv_rep) (struct net_device *dev,
+	struct neighbour *n, __u32 ip, unsigned char *ha) = __dflt_arp_hook_rcv_rep;
+int (* arp_hook_rcv_req) (struct net_device *dev, struct rtable *rt,
+	__u32 sip, __u32 tip) = __dflt_arp_hook_rcv_req;
+
+void arp_hook_register(
+	void(*rep)(struct net_device *, struct neighbour *, __u32, unsigned char *),
+	int(*req)(struct net_device *, struct rtable *, __u32 , __u32))
+{
+	arp_hook_rcv_rep = rep ? rep : __dflt_arp_hook_rcv_rep;
+	arp_hook_rcv_req = req ? req : __dflt_arp_hook_rcv_req;
+}
+#endif
 
 static u32 arp_hash(const void *pkey, const struct net_device *dev)
 {
@@ -859,11 +887,26 @@ int arp_process(struct sk_buff *skb)
 			n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
 			if (n) {
 				int dont_send = 0;
-
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+				struct net_device *dev2 = NULL;
+				struct in_device *in_dev2;
+				extern int sysctl_ip_arp_restrict;
+#endif
 				if (!dont_send)
 					dont_send |= arp_ignore(in_dev,dev,sip,tip);
 				if (!dont_send && IN_DEV_ARPFILTER(in_dev))
-					dont_send |= arp_filter(sip,tip,dev); 
+					dont_send |= arp_filter(sip,tip,dev);
+
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+				if ((sysctl_ip_arp_restrict) &&
+					((dev2 = ip_dev_find(tip)) != NULL) &&
+					(dev2!=dev) &&
+					((in_dev2=dev2->ip_ptr) != NULL)) {
+					dont_send |= 1;
+				}
+				if (dev2)
+					dev_put(dev2);
+#endif
 				if (!dont_send)
 					arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha);
 
@@ -874,6 +917,9 @@ int arp_process(struct sk_buff *skb)
 			if ((rt->rt_flags&RTCF_DNAT) ||
 			    (addr_type == RTN_UNICAST  && rt->u.dst.dev != dev &&
 			     (arp_fwd_proxy(in_dev, rt) || pneigh_lookup(&arp_tbl, &tip, dev, 0)))) {
+#ifdef CONFIG_ARKOON_ARP_HOOK
+ak_arp_hook_send_it:
+#endif
 				n = neigh_event_ns(&arp_tbl, sha, &sip, dev);
 				if (n)
 					neigh_release(n);
@@ -889,6 +935,11 @@ int arp_process(struct sk_buff *skb)
 				}
 				goto out;
 			}
+#ifdef CONFIG_ARKOON_ARP_HOOK
+			else if (arp_hook_rcv_req(dev, rt, sip, tip)) {
+				goto ak_arp_hook_send_it;
+			}
+#endif
 		}
 	}
 
@@ -907,6 +958,13 @@ int arp_process(struct sk_buff *skb)
 		n = __neigh_lookup(&arp_tbl, &sip, dev, -1);
 #endif
 
+#ifdef CONFIG_ARKOON_ARP_HOOK
+	if ((arp->ar_op == __constant_htons(ARPOP_REPLY)) &&
+		(inet_addr_type(sip)==RTN_UNICAST) && (skb->pkt_type==PACKET_HOST)) {
+		arp_hook_rcv_rep (dev, n, sip, sha);
+	}
+#endif
+
 	if (n) {
 		int state = NUD_REACHABLE;
 		int override = 0;
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 9cabf22..6fb1384 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -292,6 +292,9 @@ static inline int ip_queue_xmit2(struct sk_buff *skb)
 	struct rtable *rt = (struct rtable *)skb->dst;
 	struct net_device *dev;
 	struct iphdr *iph = skb->nh.iph;
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+	extern int sysctl_ip_stack_fragment;
+#endif
 
 	dev = rt->u.dst.dev;
 
@@ -313,7 +316,11 @@ static inline int ip_queue_xmit2(struct sk_buff *skb)
 		iph = skb->nh.iph;
 	}
 
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+	if ((skb->len > skb->dst->pmtu) && (sysctl_ip_stack_fragment))
+#else
 	if (skb->len > rt->u.dst.pmtu)
+#endif
 		goto fragment;
 
 	ip_select_ident(iph, &rt->u.dst, sk);
@@ -895,6 +902,8 @@ int ip_fragment(struct sk_buff *skb, int (*output)(struct sk_buff*))
 #endif
 #endif
 
+		AK_SKB_HEADERCOPY(skb,skb2);
+
 		/*
 		 *	Put this fragment into the sending queue.
 		 */
@@ -986,6 +995,14 @@ void ip_send_reply(struct sock *sk, struct sk_buff *skb, struct ip_reply_arg *ar
 			daddr = replyopts.opt.faddr;
 	}
 
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+	if (IPCB(skb)->redirport) {
+		if (ip_route_output(&rt, daddr, skb->nh.iph->daddr,
+			RT_TOS(skb->nh.iph->tos), 0))
+			return;
+	}
+	else
+#endif
 	if (ip_route_output(&rt, daddr, rt->rt_spec_dst, RT_TOS(skb->nh.iph->tos), 0))
 		return;
 
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 81e98dc..7a9e429 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1529,11 +1529,23 @@ int ip_route_input_slow(struct sk_buff *skb, u32 daddr, u32 saddr,
 		flags |= RTCF_DOREDIRECT;
 
 	if (skb->protocol != htons(ETH_P_IP)) {
+#ifdef CONFIG_ARKOON_ARP_HOOK
+		/**
+		 * Not IP (i.e. ARP).
+		 * ip_route_input() must not fail for arp_hook to succeed. So we need
+		 * to create routes for theses arp entries if arp_hook is enabled.
+		 */
+		extern int (* arp_hook_rcv_req) (struct net_device *dev,
+			struct rtable *rt, __u32 sip, __u32 tip);
+		if (arp_hook_rcv_req(dev, NULL, saddr, daddr) == 0)
+			goto e_inval;
+#else
 		/* Not IP (i.e. ARP). Do not create route, if it is
 		 * invalid for proxy arp. DNAT routes are always valid.
 		 */
 		if (out_dev == in_dev && !(flags & RTCF_DNAT))
 			goto e_inval;
+#endif
 	}
 
 	rth = dst_alloc(&ipv4_dst_ops);
@@ -1784,6 +1796,9 @@ int ip_route_output_slow(struct rtable **rp, const struct rt_key *oldkey)
 	int free_res = 0;
 	int err;
 	u32 tos;
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+	u32 nochksrc = (oldkey->tos & RTO_TPROXY);
+#endif
 
 	tos		= oldkey->tos & (IPTOS_RT_MASK | RTO_ONLINK);
 	key.dst		= oldkey->dst;
@@ -1811,7 +1826,14 @@ int ip_route_output_slow(struct rtable **rp, const struct rt_key *oldkey)
 		/* It is equivalent to inet_addr_type(saddr) == RTN_LOCAL */
 		dev_out = ip_dev_find(oldkey->src);
 		if (dev_out == NULL)
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+		{
+			if ((nochksrc) || (inet_addr_type(oldkey->src)!= RTN_UNICAST))
+				goto out;
+		}
+#else
 			goto out;
+#endif
 
 		/* I removed check for oif == dev_out->oif here.
 		   It was wrong by three reasons:
@@ -1822,6 +1844,9 @@ int ip_route_output_slow(struct rtable **rp, const struct rt_key *oldkey)
 		 */
 
 		if (oldkey->oif == 0
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+			&& dev_out
+#endif
 		    && (MULTICAST(oldkey->dst) || oldkey->dst == 0xFFFFFFFF)) {
 			/* Special hack: user can direct multicasts
 			   and limited broadcast via necessary interface
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 2d75f45..e7e71ef 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -138,6 +138,9 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
 	req->snt_isn		= cookie; 
 	req->mss		= mss;
  	req->rmt_port		= skb->h.th->source;
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+ 	req->lcl_port		= skb->h.th->dest;
+#endif
 	req->af.v4_req.loc_addr = skb->nh.iph->daddr;
 	req->af.v4_req.rmt_addr = skb->nh.iph->saddr;
 	req->class		= &or_ipv4; /* for savety */
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index acdb779..2212bc7 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -62,6 +62,11 @@ extern ctl_table ipv4_route_table[];
 
 #ifdef CONFIG_SYSCTL
 
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+int sysctl_ip_stack_fragment = 1;
+int sysctl_ip_arp_restrict = 0;
+#endif
+
 static
 int ipv4_sysctl_forward(ctl_table *ctl, int write, struct file * filp,
 			void *buffer, size_t *lenp)
@@ -120,6 +125,12 @@ ctl_table ipv4_table[] = {
 	{NET_IPV4_NONLOCAL_BIND, "ip_nonlocal_bind",
 	 &sysctl_ip_nonlocal_bind, sizeof(int), 0644, NULL,
 	 &proc_dointvec},
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+	{NET_IPV4_STACK_FRAGMENT, "ip_stack_fragment",
+	 &sysctl_ip_stack_fragment, sizeof(int), 0644, NULL, &proc_dointvec},
+	{NET_IPV4_ARP_RESTRICT, "ip_arp_restrict",
+	 &sysctl_ip_arp_restrict, sizeof(int), 0644, NULL, &proc_dointvec},
+#endif
 	{NET_IPV4_TCP_SYN_RETRIES, "tcp_syn_retries",
 	 &sysctl_tcp_syn_retries, sizeof(int), 0644, NULL, &proc_dointvec},
 	{NET_TCP_SYNACK_RETRIES, "tcp_synack_retries",
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index a67015f..ed178a5 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -1819,6 +1819,13 @@ static int tcp_close_state(struct sock *sk)
 
 void tcp_shutdown(struct sock *sk, int how)
 {
+#ifdef CONFIG_ARKOON_RST_SHUTDOWN
+	if (how & RST_SHUTDOWN) {
+		tcp_set_state(sk, TCP_CLOSE);
+		tcp_send_active_reset(sk, GFP_KERNEL);
+		return;
+	}
+#endif
 	/*	We need to grab some memory, and put together a FIN,
 	 *	and then put it into the queue to be sent.
 	 *		Tim MacKenzie(tym@dibbler.cs.monash.edu.au) 4 Dec '92.
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index fa56df8..e2d9abc 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -879,6 +879,9 @@ static __inline__ u32 tcp_v4_synq_hash(u32 raddr, u16 rport, u32 rnd)
 static struct open_request *tcp_v4_search_req(struct tcp_opt *tp, 
 					      struct open_request ***prevp,
 					      __u16 rport,
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+					      __u16 lport,
+#endif
 					      __u32 raddr, __u32 laddr)
 {
 	struct tcp_listen_opt *lopt = tp->listen_opt;
@@ -888,6 +891,9 @@ static struct open_request *tcp_v4_search_req(struct tcp_opt *tp,
 	     (req = *prev) != NULL;
 	     prev = &req->dl_next) {
 		if (req->rmt_port == rport &&
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+			req->lcl_port == lport &&
+#endif
 		    req->af.v4_req.rmt_addr == raddr &&
 		    req->af.v4_req.loc_addr == laddr &&
 		    TCP_INET_FAMILY(req->class->family)) {
@@ -1057,6 +1063,9 @@ void tcp_v4_err(struct sk_buff *skb, u32 info)
 
 		req = tcp_v4_search_req(tp, &prev,
 					th->dest,
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+					th->source,
+#endif
 					iph->daddr, iph->saddr); 
 		if (!req)
 			goto out;
@@ -1561,6 +1570,9 @@ struct sock * tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
 	newsk->daddr = req->af.v4_req.rmt_addr;
 	newsk->saddr = req->af.v4_req.loc_addr;
 	newsk->rcv_saddr = req->af.v4_req.loc_addr;
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+	newsk->sport = req->lcl_port;
+#endif
 	newsk->protinfo.af_inet.opt = req->af.v4_req.opt;
 	req->af.v4_req.opt = NULL;
 	newsk->protinfo.af_inet.mc_index = tcp_v4_iif(skb);
@@ -1598,6 +1610,9 @@ static struct sock *tcp_v4_hnd_req(struct sock *sk,struct sk_buff *skb)
 	/* Find possible connection requests. */
 	req = tcp_v4_search_req(tp, &prev,
 				th->source,
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+				th->dest,
+#endif
 				iph->saddr, iph->daddr);
 	if (req)
 		return tcp_check_req(sk, skb, req, prev);
@@ -1749,6 +1764,16 @@ int tcp_v4_rcv(struct sk_buff *skb)
 	TCP_SKB_CB(skb)->flags = skb->nh.iph->tos;
 	TCP_SKB_CB(skb)->sacked = 0;
 
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+	if (IPCB(skb)->redirport) {
+		sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source,
+			skb->nh.iph->daddr, IPCB(skb)->redirport, tcp_v4_iif(skb));
+		if (!sk)
+			sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source,
+				ntohl(INADDR_LOOPBACK), IPCB(skb)->redirport, tcp_v4_iif(skb));
+	}
+	else
+#endif
 	sk = __tcp_v4_lookup(skb->nh.iph->saddr, th->source,
 			     skb->nh.iph->daddr, ntohs(th->dest), tcp_v4_iif(skb));
 
@@ -2083,7 +2108,11 @@ static void get_openreq(struct sock *sk, struct open_request *req, char *tmpbuf,
 		" %02X %08X:%08X %02X:%08X %08X %5d %8d %u %d %p",
 		i,
 		req->af.v4_req.loc_addr,
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+		ntohs(req->lcl_port),
+#else
 		ntohs(sk->sport),
+#endif
 		req->af.v4_req.rmt_addr,
 		ntohs(req->rmt_port),
 		TCP_SYN_RECV,
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 150f7db..2730af5 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -1138,7 +1138,11 @@ struct sk_buff * tcp_make_synack(struct sock *sk, struct dst_entry *dst,
 	th->syn = 1;
 	th->ack = 1;
 	TCP_ECN_make_synack(req, th);
+#ifdef CONFIG_IP_TRANSPARENT_PROXY
+	th->source = req->lcl_port;
+#else
 	th->source = sk->sport;
+#endif
 	th->dest = req->rmt_port;
 	TCP_SKB_CB(skb)->seq = req->snt_isn;
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq + 1;
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index c0b89c1..fe67ed1 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -98,6 +98,13 @@
 #include <net/inet_common.h>
 #include <net/checksum.h>
 
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+  /* NAT-Traversal needed for Arkoon */
+  #ifndef CONFIG_IPSEC_NAT_TRAVERSAL
+    #define CONFIG_IPSEC_NAT_TRAVERSAL
+  #endif
+#endif
+
 /*
  *	Snmp MIB for the UDP layer
  */
@@ -860,6 +867,9 @@ static void udp_close(struct sock *sk, long timeout)
 
 static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 {
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	struct udp_opt *tp =  &(sk->tp_pinfo.af_udp);
+#endif
 	/*
 	 *	Charge it to the socket, dropping if the queue is full.
 	 */
@@ -877,6 +887,38 @@ static int udp_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 	}
 #endif
 
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+	if (tp->esp_in_udp) {
+		/*
+		 * Set skb->sk and xmit packet to ipsec_rcv.
+		 *
+		 * If ret != 0, ipsec_rcv refused the packet (not ESPinUDP),
+		 * restore skb->sk and fall back to sock_queue_rcv_skb
+		 */
+		struct inet_protocol *esp = NULL;
+
+#ifdef CONFIG_IPSEC
+		extern struct inet_protocol esp_protocol;
+		esp = &esp_protocol;
+#else
+		for (esp = (struct inet_protocol *)inet_protos[IPPROTO_ESP & (MAX_INET_PROTOS - 1)];
+			(esp) && (esp->protocol != IPPROTO_ESP);
+			esp = esp->next);
+#endif
+
+		if (esp && esp->handler) {
+			struct sock *sav_sk = skb->sk;
+			skb->sk = sk;
+			if (esp->handler(skb) == 0) {
+				skb->sk = sav_sk;
+				/* not sure we might count ESPinUDP as UDP... */
+				UDP_INC_STATS_BH(UdpInDatagrams);
+				return 0;
+			}
+			skb->sk = sav_sk;
+		}
+	}
+#endif
 	if (sock_queue_rcv_skb(sk,skb)<0) {
 		UDP_INC_STATS_BH(UdpInErrors);
 		IP_INC_STATS_BH(IpInDiscards);
@@ -1100,13 +1142,55 @@ out:
 	return len;
 }
 
+#if 1
+static int udp_setsockopt(struct sock *sk, int level, int optname,
+	char *optval, int optlen)
+{
+	struct udp_opt *tp = &(sk->tp_pinfo.af_udp);
+	int val;
+	int err = 0;
+
+	if (level != SOL_UDP)
+		return ip_setsockopt(sk, level, optname, optval, optlen);
+
+	if(optlen<sizeof(int))
+		return -EINVAL;
+
+	if (get_user(val, (int *)optval))
+		return -EFAULT;
+	
+	lock_sock(sk);
+
+	switch(optname) {
+#ifdef CONFIG_IPSEC_NAT_TRAVERSAL
+#ifndef UDP_ESPINUDP
+#define UDP_ESPINUDP 100
+#endif
+		case UDP_ESPINUDP:
+			tp->esp_in_udp = val;
+			break;
+#endif
+		default:
+			err = -ENOPROTOOPT;
+			break;
+	}
+
+	release_sock(sk);
+	return err;
+}
+#endif
+
 struct proto udp_prot = {
  	name:		"UDP",
 	close:		udp_close,
 	connect:	udp_connect,
 	disconnect:	udp_disconnect,
 	ioctl:		udp_ioctl,
+#if 1
+	setsockopt:	udp_setsockopt,
+#else
 	setsockopt:	ip_setsockopt,
+#endif
 	getsockopt:	ip_getsockopt,
 	sendmsg:	udp_sendmsg,
 	recvmsg:	udp_recvmsg,
diff --git a/net/netsyms.c b/net/netsyms.c
index 9a21703..9551c8e 100644
--- a/net/netsyms.c
+++ b/net/netsyms.c
@@ -627,4 +627,16 @@ EXPORT_SYMBOL(iw_handler_get_thrspy);
 EXPORT_SYMBOL(wireless_spy_update);
 #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
 
+#ifdef CONFIG_ARKOON_ARP_HOOK
+EXPORT_SYMBOL(arp_hook_register);
+#endif
+#ifdef CONFIG_ARKOON_DEV_IOCTL_RESTRICT
+EXPORT_SYMBOL(dev_ioctl_set_restrict);
+#endif
+#ifdef CONFIG_ARKOON_REQUIREMENTS
+extern int sysctl_ip_stack_fragment;
+EXPORT_SYMBOL(sysctl_ip_stack_fragment);
+EXPORT_SYMBOL(ip_local_deliver);
+#endif
+
 #endif  /* CONFIG_NET */

