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 +# 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 #include #include - +#ifdef CONFIG_ARKOON_REQUIREMENTS +#include +#endif #include #include @@ -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 #include #include +#ifdef CONFIG_MD #include +#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, * Florian La Roche, * + * 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 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 #include #include +#include + +#include +#include + #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 #include +#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(optlenesp_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 */