## Automatically generated incremental diff
## From:   linux-2.5.69-bk15
## To:     linux-2.5.69-bk16
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.5.69-bk15/Documentation/pci.txt linux-2.5.69-bk16/Documentation/pci.txt
--- linux-2.5.69-bk15/Documentation/pci.txt	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk16/Documentation/pci.txt	2003-05-23 04:36:20.000000000 -0700
@@ -45,8 +45,6 @@
 	id_table	Pointer to table of device ID's the driver is
 			interested in.  Most drivers should export this
 			table using MODULE_DEVICE_TABLE(pci,...).
-			Set to NULL to call probe() function for every
-			PCI device known to the system.
 	probe		Pointer to a probing function which gets called (during
 			execution of pci_register_driver for already existing
 			devices or later if a new device gets inserted) for all
@@ -83,6 +81,28 @@
 	class_mask	of the class are honored during the comparison.
 	driver_data	Data private to the driver.
 
+Most drivers don't need to use the driver_data field.  Best practice
+for use of driver_data is to use it as an index into a static list of
+equivalant device types, not to use it as a pointer.
+
+Have a table entry {PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID}
+to have probe() called for every PCI device known to the system.
+
+New PCI IDs may be added to a device driver at runtime by writing
+to the file /sys/bus/pci/drivers/{driver}/new_id.  When added, the
+driver will probe for all devices it can support.
+
+echo "vendor device subvendor subdevice class class_mask driver_data" > \
+ /sys/bus/pci/drivers/{driver}/new_id
+where all fields are passed in as hexadecimal values (no leading 0x).
+Users need pass only as many fields as necessary; vendor, device,
+subvendor, and subdevice fields default to PCI_ANY_ID (FFFFFFFF),
+class and classmask fields default to 0, and driver_data defaults to
+0UL.  Device drivers must call
+   pci_dynids_set_use_driver_data(pci_driver *, 1)
+in order for the driver_data field to get passed to the driver.
+Otherwise, only a 0 is passed in that field.
+
 When the driver exits, it just calls pci_unregister_driver() and the PCI layer
 automatically calls the remove hook for all devices handled by the driver.
 
diff -urN linux-2.5.69-bk15/Makefile linux-2.5.69-bk16/Makefile
--- linux-2.5.69-bk15/Makefile	2003-05-23 04:36:12.000000000 -0700
+++ linux-2.5.69-bk16/Makefile	2003-05-23 04:36:21.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 5
 SUBLEVEL = 69
-EXTRAVERSION = -bk15
+EXTRAVERSION = -bk16
 
 # *DOCUMENTATION*
 # To see a list of typical targets execute "make help"
diff -urN linux-2.5.69-bk15/arch/alpha/kernel/core_marvel.c linux-2.5.69-bk16/arch/alpha/kernel/core_marvel.c
--- linux-2.5.69-bk15/arch/alpha/kernel/core_marvel.c	2003-05-23 04:36:12.000000000 -0700
+++ linux-2.5.69-bk16/arch/alpha/kernel/core_marvel.c	2003-05-23 04:36:21.000000000 -0700
@@ -1075,7 +1075,6 @@
 	/*
 	 * Fill it in.
 	 */
-	agp->type = ALPHA_CORE_AGP;
 	agp->hose = hose;
 	agp->private = NULL;
 	agp->ops = &marvel_agp_ops;
diff -urN linux-2.5.69-bk15/arch/alpha/kernel/core_titan.c linux-2.5.69-bk16/arch/alpha/kernel/core_titan.c
--- linux-2.5.69-bk15/arch/alpha/kernel/core_titan.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk16/arch/alpha/kernel/core_titan.c	2003-05-23 04:36:21.000000000 -0700
@@ -763,7 +763,6 @@
 	/*
 	 * Fill it in.
 	 */
-	agp->type = ALPHA_CORE_AGP;
 	agp->hose = hose;
 	agp->private = port;
 	agp->ops = &titan_agp_ops;
diff -urN linux-2.5.69-bk15/arch/i386/kernel/apm.c linux-2.5.69-bk16/arch/i386/kernel/apm.c
--- linux-2.5.69-bk15/arch/i386/kernel/apm.c	2003-05-23 04:36:12.000000000 -0700
+++ linux-2.5.69-bk16/arch/i386/kernel/apm.c	2003-05-23 04:36:21.000000000 -0700
@@ -2013,7 +2013,7 @@
 
 	apm_proc = create_proc_info_entry("apm", 0, NULL, apm_get_info);
 	if (apm_proc)
-		SET_MODULE_OWNER(apm_proc);
+		apm_proc->owner = THIS_MODULE;
 
 	kernel_thread(apm, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD);
 
diff -urN linux-2.5.69-bk15/drivers/base/bus.c linux-2.5.69-bk16/drivers/base/bus.c
--- linux-2.5.69-bk15/drivers/base/bus.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk16/drivers/base/bus.c	2003-05-23 04:36:21.000000000 -0700
@@ -316,7 +316,7 @@
  *	Note that we ignore the error from bus_match(), since it's perfectly
  *	valid for a driver not to bind to any devices.
  */
-static void driver_attach(struct device_driver * drv)
+void driver_attach(struct device_driver * drv)
 {
 	struct bus_type * bus = drv->bus;
 	struct list_head * entry;
diff -urN linux-2.5.69-bk15/drivers/char/agp/agp.h linux-2.5.69-bk16/drivers/char/agp/agp.h
--- linux-2.5.69-bk15/drivers/char/agp/agp.h	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/agp.h	2003-05-23 04:36:21.000000000 -0700
@@ -102,15 +102,15 @@
 	int (*configure)(void);
 	void (*agp_enable)(u32);
 	void (*cleanup)(void);
-	void (*tlb_flush)(agp_memory *);
+	void (*tlb_flush)(struct agp_memory *);
 	unsigned long (*mask_memory)(unsigned long, int);
 	void (*cache_flush)(void);
 	int (*create_gatt_table)(void);
 	int (*free_gatt_table)(void);
-	int (*insert_memory)(agp_memory *, off_t, int);
-	int (*remove_memory)(agp_memory *, off_t, int);
-	agp_memory *(*alloc_by_type) (size_t, int);
-	void (*free_by_type)(agp_memory *);
+	int (*insert_memory)(struct agp_memory *, off_t, int);
+	int (*remove_memory)(struct agp_memory *, off_t, int);
+	struct agp_memory *(*alloc_by_type) (size_t, int);
+	void (*free_by_type)(struct agp_memory *);
 	void *(*agp_alloc_page)(void);
 	void (*agp_destroy_page)(void *);
 };
@@ -375,11 +375,11 @@
 void agp_generic_enable(u32 mode);
 int agp_generic_create_gatt_table(void);
 int agp_generic_free_gatt_table(void);
-agp_memory *agp_create_memory(int scratch_pages);
-int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type);
-int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type);
-agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
-void agp_generic_free_by_type(agp_memory * curr);
+struct agp_memory *agp_create_memory(int scratch_pages);
+int agp_generic_insert_memory(struct agp_memory *mem, off_t pg_start, int type);
+int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type);
+struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
+void agp_generic_free_by_type(struct agp_memory *curr);
 void *agp_generic_alloc_page(void);
 void agp_generic_destroy_page(void *addr);
 void agp_free_key(int key);
diff -urN linux-2.5.69-bk15/drivers/char/agp/ali-agp.c linux-2.5.69-bk16/drivers/char/agp/ali-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/ali-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/ali-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -33,14 +33,14 @@
 	return 0;
 }
 
-static void ali_tlbflush(agp_memory * mem)
+static void ali_tlbflush(struct agp_memory *mem)
 {
 	u32 temp;
 
 	pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
-// clear tag
-	pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL,
-			((temp & 0xfffffff0) | 0x00000001|0x00000002));
+	temp &= 0xfffffff0;
+	temp |= (1<<0 | 1<<1);
+	pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL, temp);
 }
 
 static void ali_cleanup(void)
diff -urN linux-2.5.69-bk15/drivers/char/agp/alpha-agp.c linux-2.5.69-bk16/drivers/char/agp/alpha-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/alpha-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/alpha-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -68,7 +68,7 @@
 	agp->ops->cleanup(agp);
 }
 
-static void alpha_core_agp_tlbflush(agp_memory *mem)
+static void alpha_core_agp_tlbflush(struct agp_memory *mem)
 {
 	alpha_agp_info *agp = agp_bridge->dev_private_data;
 	alpha_mv.mv_pci_tbi(agp->hose, 0, -1);
@@ -86,7 +86,7 @@
 	agp_device_command(agp->mode.lw, 0);
 }
 
-static int alpha_core_agp_insert_memory(agp_memory *mem, off_t pg_start, 
+static int alpha_core_agp_insert_memory(struct agp_memory *mem, off_t pg_start, 
 					int type)
 {
 	alpha_agp_info *agp = agp_bridge->dev_private_data;
@@ -104,7 +104,7 @@
 	return status;
 }
 
-static int alpha_core_agp_remove_memory(agp_memory *mem, off_t pg_start, 
+static int alpha_core_agp_remove_memory(struct agp_memory *mem, off_t pg_start, 
 					int type)
 {
 	alpha_agp_info *agp = agp_bridge->dev_private_data;
@@ -117,17 +117,18 @@
 
 struct agp_bridge_driver alpha_core_agp_driver = {
 	.owner			= THIS_MODULE,
-	.aperture_sizes		= aper_size,
-	.current_size		= aper_size,	/* only one entry */
-	.size_type		= FIXED_APER_SIZE,
+	.aperture_sizes		= alpha_core_agp_sizes,
 	.num_aperture_sizes	= 1,
-	.configure		= alpha_core_agp_configure,
+	.size_type		= FIXED_APER_SIZE,
+	.cant_use_aperture	= 1,
+	.masks			= NULL,
+	
 	.fetch_size		= alpha_core_agp_fetch_size,
+	.configure		= alpha_core_agp_configure,
+	.agp_enable		= alpha_core_agp_enable,
 	.cleanup		= alpha_core_agp_cleanup,
 	.tlb_flush		= alpha_core_agp_tlbflush,
 	.mask_memory		= agp_generic_mask_memory,
-	.masks			= NULL,
-	.agp_enable		= alpha_core_agp_enable,
 	.cache_flush		= global_cache_flush,
 	.create_gatt_table	= alpha_core_agp_nop,
 	.free_gatt_table	= alpha_core_agp_nop,
@@ -137,9 +138,6 @@
 	.free_by_type		= agp_generic_free_by_type,
 	.agp_alloc_page		= agp_generic_alloc_page,
 	.agp_destroy_page	= agp_generic_destroy_page,
-	.mode			= agp->capability.lw,
-	.cant_use_aperture	= 1,
-	.vm_ops			= &alpha_core_agp_vm_ops,
 };
 
 struct agp_bridge_data *alpha_bridge;
@@ -160,11 +158,9 @@
 	 * Build the aperture size descriptor
 	 */
 	aper_size = alpha_core_agp_sizes;
-	if (!aper_size)
-		return -ENOMEM;
 	aper_size->size = agp->aperture.size / (1024 * 1024);
 	aper_size->num_entries = agp->aperture.size / PAGE_SIZE;
-	aper_size->page_order = ffs(aper_size->num_entries / 1024) - 1;
+	aper_size->page_order = __ffs(aper_size->num_entries / 1024);
 
 	/*
 	 * Build a fake pci_dev struct
@@ -181,8 +177,11 @@
 		goto fail;
 
 	alpha_bridge->driver = &alpha_core_agp_driver;
+	alpha_bridge->vm_ops = &alpha_core_agp_vm_ops;
+	alpha_bridge->current_size = aper_size; /* only 1 size */
 	alpha_bridge->dev_private_data = agp;
 	alpha_bridge->dev = pdev;
+	alpha_bridge->mode = agp->capability.lw;
 
 	printk(KERN_INFO "Detected AGP on hose %d\n", agp->hose->index);
 	return agp_add_bridge(alpha_bridge);
diff -urN linux-2.5.69-bk15/drivers/char/agp/amd-k7-agp.c linux-2.5.69-bk16/drivers/char/agp/amd-k7-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/amd-k7-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/amd-k7-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -265,12 +265,12 @@
  * entries.
  */
 
-static void amd_irongate_tlbflush(agp_memory *temp)
+static void amd_irongate_tlbflush(struct agp_memory *temp)
 {
 	OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
 }
 
-static int amd_insert_memory(agp_memory * mem, off_t pg_start, int type)
+static int amd_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
 {
 	int i, j, num_entries;
 	unsigned long *cur_gatt;
@@ -308,7 +308,7 @@
 	return 0;
 }
 
-static int amd_remove_memory(agp_memory *mem, off_t pg_start, int type)
+static int amd_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
 {
 	int i;
 	unsigned long *cur_gatt;
diff -urN linux-2.5.69-bk15/drivers/char/agp/amd-k8-agp.c linux-2.5.69-bk16/drivers/char/agp/amd-k8-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/amd-k8-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/amd-k8-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -38,13 +38,13 @@
 	pci_write_config_dword (dev, AMD_X86_64_GARTCACHECTL, tmp);
 }
 
-static void amd_x86_64_tlbflush(agp_memory *temp)
+static void amd_x86_64_tlbflush(struct agp_memory *temp)
 {
 	for_each_nb()
 		flush_x86_64_tlb(hammers[gart_iterator]);
 }
 
-static int x86_64_insert_memory(agp_memory * mem, off_t pg_start, int type)
+static int x86_64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
 {
 	int i, j, num_entries;
 	long tmp;
diff -urN linux-2.5.69-bk15/drivers/char/agp/frontend.c linux-2.5.69-bk16/drivers/char/agp/frontend.c
--- linux-2.5.69-bk15/drivers/char/agp/frontend.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/frontend.c	2003-05-23 04:36:21.000000000 -0700
@@ -42,9 +42,9 @@
 
 static struct agp_front_data agp_fe;
 
-static agp_memory *agp_find_mem_by_key(int key)
+static struct agp_memory *agp_find_mem_by_key(int key)
 {
-	agp_memory *curr;
+	struct agp_memory *curr;
 
 	if (agp_fe.current_controller == NULL)
 		return NULL;
@@ -61,10 +61,10 @@
 	return curr;
 }
 
-static void agp_remove_from_pool(agp_memory * temp)
+static void agp_remove_from_pool(struct agp_memory *temp)
 {
-	agp_memory *prev;
-	agp_memory *next;
+	struct agp_memory *prev;
+	struct agp_memory *next;
 
 	/* Check to see if this is even in the memory pool */
 
@@ -218,9 +218,9 @@
 /* End - Routines for managing each client's segment list */
 
 /* This function must only be called when current_controller != NULL */
-static void agp_insert_into_pool(agp_memory * temp)
+static void agp_insert_into_pool(struct agp_memory * temp)
 {
-	agp_memory *prev;
+	struct agp_memory *prev;
 
 	prev = agp_fe.current_controller->pool;
 
@@ -289,15 +289,15 @@
  * Wrappers for agp_free_memory & agp_allocate_memory 
  * These make sure that internal lists are kept updated.
  */
-static void agp_free_memory_wrap(agp_memory * memory)
+static void agp_free_memory_wrap(struct agp_memory *memory)
 {
 	agp_remove_from_pool(memory);
 	agp_free_memory(memory);
 }
 
-static agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type)
+static struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type)
 {
-	agp_memory *memory;
+	struct agp_memory *memory;
 
 	memory = agp_allocate_memory(pg_count, type);
    	printk(KERN_DEBUG "agp_allocate_memory: %p\n", memory);
@@ -383,8 +383,8 @@
 
 static void agp_remove_all_memory(struct agp_controller *controller)
 {
-	agp_memory *memory;
-	agp_memory *temp;
+	struct agp_memory *memory;
+	struct agp_memory *temp;
 
 	memory = controller->pool;
 
@@ -596,7 +596,7 @@
 	unsigned long offset;
 	struct agp_client *client;
 	struct agp_file_private *priv = file->private_data;
-	agp_kern_info kerninfo;
+	struct agp_kern_info kerninfo;
 
 	down(&(agp_fe.agp_mutex));
 
@@ -756,7 +756,7 @@
 static int agpioc_info_wrap(struct agp_file_private *priv, unsigned long arg)
 {
 	struct agp_info userinfo;
-	agp_kern_info kerninfo;
+	struct agp_kern_info kerninfo;
 
 	agp_copy_info(&kerninfo);
 
@@ -912,7 +912,7 @@
 
 static int agpioc_allocate_wrap(struct agp_file_private *priv, unsigned long arg)
 {
-	agp_memory *memory;
+	struct agp_memory *memory;
 	struct agp_allocate alloc;
 
 	DBG("");
@@ -936,7 +936,7 @@
 
 static int agpioc_deallocate_wrap(struct agp_file_private *priv, unsigned long arg)
 {
-	agp_memory *memory;
+	struct agp_memory *memory;
 
 	DBG("");
 	memory = agp_find_mem_by_key((int) arg);
@@ -951,7 +951,7 @@
 static int agpioc_bind_wrap(struct agp_file_private *priv, unsigned long arg)
 {
 	struct agp_bind bind_info;
-	agp_memory *memory;
+	struct agp_memory *memory;
 
 	DBG("");
 	if (copy_from_user(&bind_info, (void *) arg, sizeof(struct agp_bind)))
@@ -967,7 +967,7 @@
 
 static int agpioc_unbind_wrap(struct agp_file_private *priv, unsigned long arg)
 {
-	agp_memory *memory;
+	struct agp_memory *memory;
 	struct agp_unbind unbind;
 
 	DBG("");
diff -urN linux-2.5.69-bk15/drivers/char/agp/generic.c linux-2.5.69-bk16/drivers/char/agp/generic.c
--- linux-2.5.69-bk15/drivers/char/agp/generic.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/generic.c	2003-05-23 04:36:21.000000000 -0700
@@ -69,16 +69,16 @@
 }
 
 
-agp_memory *agp_create_memory(int scratch_pages)
+struct agp_memory *agp_create_memory(int scratch_pages)
 {
-	agp_memory *new;
+	struct agp_memory *new;
 
-	new = kmalloc(sizeof(agp_memory), GFP_KERNEL);
+	new = kmalloc(sizeof(struct agp_memory), GFP_KERNEL);
 
 	if (new == NULL)
 		return NULL;
 
-	memset(new, 0, sizeof(agp_memory));
+	memset(new, 0, sizeof(struct agp_memory));
 	new->key = agp_get_key();
 
 	if (new->key < 0) {
@@ -105,7 +105,7 @@
  *	It is the only function that can be called when the backend is not owned
  *	by the caller.  (So it can free memory on client death.)
  */
-void agp_free_memory(agp_memory * curr)
+void agp_free_memory(struct agp_memory *curr)
 {
 	size_t i;
 
@@ -143,10 +143,10 @@
  *
  *	It returns NULL whenever memory is unavailable. 
  */
-agp_memory *agp_allocate_memory(size_t page_count, u32 type)
+struct agp_memory *agp_allocate_memory(size_t page_count, u32 type)
 {
 	int scratch_pages;
-	agp_memory *new;
+	struct agp_memory *new;
 	size_t i;
 
 	if (agp_bridge->type == NOT_SUPPORTED)
@@ -267,9 +267,9 @@
  *	This function copies information about the agp bridge device and the state of
  *	the agp backend into an agp_kern_info pointer.
  */
-int agp_copy_info(agp_kern_info * info)
+int agp_copy_info(struct agp_kern_info *info)
 {
-	memset(info, 0, sizeof(agp_kern_info));
+	memset(info, 0, sizeof(struct agp_kern_info));
 	if (!agp_bridge || agp_bridge->type == NOT_SUPPORTED ||
 	    !agp_bridge->version) {
 		info->chipset = NOT_SUPPORTED;
@@ -311,12 +311,15 @@
  *	It returns -EINVAL if the pointer == NULL.
  *	It returns -EBUSY if the area of the table requested is already in use.
  */
-int agp_bind_memory(agp_memory * curr, off_t pg_start)
+int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
 {
 	int ret_val;
 
-	if ((agp_bridge->type == NOT_SUPPORTED) ||
-	    (curr == NULL) || (curr->is_bound == TRUE)) {
+	if ((agp_bridge->type == NOT_SUPPORTED) || (curr == NULL))
+		return -EINVAL;
+
+	if (curr->is_bound == TRUE) {
+		printk (KERN_INFO PFX "memory %p is already bound!\n", curr);
 		return -EINVAL;
 	}
 	if (curr->is_flushed == FALSE) {
@@ -343,15 +346,17 @@
  * It returns -EINVAL if this piece of agp_memory is not currently bound to
  * the graphics aperture translation table or if the agp_memory pointer == NULL
  */
-int agp_unbind_memory(agp_memory * curr)
+int agp_unbind_memory(struct agp_memory *curr)
 {
 	int ret_val;
 
 	if ((agp_bridge->type == NOT_SUPPORTED) || (curr == NULL))
 		return -EINVAL;
 
-	if (curr->is_bound != TRUE)
+	if (curr->is_bound != TRUE) {
+		printk (KERN_INFO PFX "memory %p was not bound!\n", curr);
 		return -EINVAL;
+	}
 
 	ret_val = agp_bridge->driver->remove_memory(curr, curr->pg_start, curr->type);
 
@@ -374,10 +379,6 @@
 	if (!((*cmd & AGPSTAT_SBA) && (*tmp & AGPSTAT_SBA) && (*mode & AGPSTAT_SBA)))
 		*cmd &= ~AGPSTAT_SBA;
 
-	/* disable FW if it's not supported */
-	if (!((*cmd & AGPSTAT_FW) && (*tmp & AGPSTAT_FW) && (*mode & AGPSTAT_FW)))
-		*cmd &= ~AGPSTAT_FW;
-
 	/* Set speed */
 	if (!((*cmd & AGPSTAT2_4X) && (*tmp & AGPSTAT2_4X) && (*mode & AGPSTAT2_4X)))
 		*cmd &= ~AGPSTAT2_4X;
@@ -415,10 +416,6 @@
 	/* SBA *must* be supported for AGP v3 */
 	*cmd |= AGPSTAT_SBA;
 
-	/* disable FW if it's not supported */
-	if (!((*cmd & AGPSTAT_FW) && (*tmp & AGPSTAT_FW) && (*mode & AGPSTAT_FW)))
-		*cmd &= ~AGPSTAT_FW;
-
 	/*
 	 * Set speed.
 	 * Check for invalid speeds. This can happen when applications
@@ -486,9 +483,12 @@
 		     min_t(u32, (mode & AGPSTAT_RQ_DEPTH),
 			 min_t(u32, (cmd & AGPSTAT_RQ_DEPTH), (tmp & AGPSTAT_RQ_DEPTH))));
 		
-		pci_read_config_dword(device, cap_ptr+AGPSTAT, &agp3);
+		/* disable FW if it's not supported */
+		if (!((cmd & AGPSTAT_FW) && (tmp & AGPSTAT_FW) && (mode & AGPSTAT_FW)))
+			cmd &= ~AGPSTAT_FW;
 
 		/* Check to see if we are operating in 3.0 mode */
+		pci_read_config_dword(device, cap_ptr+AGPSTAT, &agp3);
 		if (agp3 & AGPSTAT_MODE_3_0) {
 			agp_v3_parse_one(&mode, &cmd, &tmp);
 		} else {
@@ -753,7 +753,7 @@
 EXPORT_SYMBOL(agp_generic_free_gatt_table);
 
 
-int agp_generic_insert_memory(agp_memory * mem, off_t pg_start, int type)
+int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
 {
 	int num_entries;
 	size_t i;
@@ -821,7 +821,7 @@
 EXPORT_SYMBOL(agp_generic_insert_memory);
 
 
-int agp_generic_remove_memory(agp_memory * mem, off_t pg_start, int type)
+int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
 {
 	size_t i;
 
@@ -842,14 +842,14 @@
 EXPORT_SYMBOL(agp_generic_remove_memory);
 
 
-agp_memory *agp_generic_alloc_by_type(size_t page_count, int type)
+struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type)
 {
 	return NULL;
 }
 EXPORT_SYMBOL(agp_generic_alloc_by_type);
 
 
-void agp_generic_free_by_type(agp_memory * curr)
+void agp_generic_free_by_type(struct agp_memory *curr)
 {
 	if (curr->memory != NULL)
 		vfree(curr->memory);
diff -urN linux-2.5.69-bk15/drivers/char/agp/hp-agp.c linux-2.5.69-bk16/drivers/char/agp/hp-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/hp-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/hp-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -212,7 +212,7 @@
 	iounmap((void *) hp->registers);
 }
 
-static void hp_zx1_tlbflush(agp_memory * mem)
+static void hp_zx1_tlbflush(struct agp_memory *mem)
 {
 	struct _hp_private *hp = &hp_private;
 
@@ -259,7 +259,8 @@
 	return 0;
 }
 
-static int hp_zx1_insert_memory(agp_memory * mem, off_t pg_start, int type)
+static int hp_zx1_insert_memory(struct agp_memory *mem, off_t pg_start,
+				int type)
 {
 	struct _hp_private *hp = &hp_private;
 	int i, k;
@@ -304,7 +305,8 @@
 	return 0;
 }
 
-static int hp_zx1_remove_memory(agp_memory * mem, off_t pg_start, int type)
+static int hp_zx1_remove_memory(struct agp_memory *mem, off_t pg_start,
+				int type)
 {
 	struct _hp_private *hp = &hp_private;
 	int i, io_pg_start, io_pg_count;
diff -urN linux-2.5.69-bk15/drivers/char/agp/i460-agp.c linux-2.5.69-bk16/drivers/char/agp/i460-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/i460-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/i460-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -153,7 +153,7 @@
 }
 
 /* There isn't anything to do here since 460 has no GART TLB. */
-static void i460_tlb_flush (agp_memory * mem)
+static void i460_tlb_flush (struct agp_memory *mem)
 {
 	return;
 }
@@ -273,7 +273,8 @@
  * PAGE_SIZE.
  */
 
-static int i460_insert_memory_small_io_page (agp_memory *mem, off_t pg_start, int type)
+static int i460_insert_memory_small_io_page (struct agp_memory *mem,
+				off_t pg_start, int type)
 {
 	unsigned long paddr, io_pg_start, io_page_size;
 	int i, j, k, num_entries;
@@ -312,7 +313,8 @@
 	return 0;
 }
 
-static int i460_remove_memory_small_io_page(agp_memory * mem, off_t pg_start, int type)
+static int i460_remove_memory_small_io_page(struct agp_memory *mem,
+				off_t pg_start, int type)
 {
 	int i;
 
@@ -377,7 +379,8 @@
 	atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
 }
 
-static int i460_insert_memory_large_io_page (agp_memory * mem, off_t pg_start, int type)
+static int i460_insert_memory_large_io_page (struct agp_memory *mem,
+				off_t pg_start, int type)
 {
 	int i, start_offset, end_offset, idx, pg, num_entries;
 	struct lp_desc *start, *end, *lp;
@@ -433,7 +436,8 @@
 	return 0;
 }
 
-static int i460_remove_memory_large_io_page (agp_memory * mem, off_t pg_start, int type)
+static int i460_remove_memory_large_io_page (struct agp_memory *mem,
+				off_t pg_start, int type)
 {
 	int i, pg, start_offset, end_offset, idx, num_entries;
 	struct lp_desc *start, *end, *lp;
@@ -471,7 +475,8 @@
 
 /* Wrapper routines to call the approriate {small_io_page,large_io_page} function */
 
-static int i460_insert_memory (agp_memory * mem, off_t pg_start, int type)
+static int i460_insert_memory (struct agp_memory *mem,
+				off_t pg_start, int type)
 {
 	if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
 		return i460_insert_memory_small_io_page(mem, pg_start, type);
@@ -479,7 +484,8 @@
 		return i460_insert_memory_large_io_page(mem, pg_start, type);
 }
 
-static int i460_remove_memory (agp_memory * mem, off_t pg_start, int type)
+static int i460_remove_memory (struct agp_memory *mem,
+				off_t pg_start, int type)
 {
 	if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
 		return i460_remove_memory_small_io_page(mem, pg_start, type);
diff -urN linux-2.5.69-bk15/drivers/char/agp/intel-agp.c linux-2.5.69-bk16/drivers/char/agp/intel-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/intel-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/intel-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -107,7 +107,7 @@
 	iounmap((void *) intel_i810_private.registers);
 }
 
-static void intel_i810_tlbflush(agp_memory * mem)
+static void intel_i810_tlbflush(struct agp_memory *mem)
 {
 	return;
 }
@@ -117,7 +117,7 @@
 	return;
 }
 
-static int intel_i810_insert_entries(agp_memory * mem, off_t pg_start,
+static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
 				int type)
 {
 	int i, j, num_entries;
@@ -166,7 +166,7 @@
 	return 0;
 }
 
-static int intel_i810_remove_entries(agp_memory * mem, off_t pg_start,
+static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start,
 				int type)
 {
 	int i;
@@ -187,9 +187,9 @@
  * pointer into hardware.
  * However the Xserver still writes to it through the agp aperture.
  */
-static agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
+static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
 {
-	agp_memory *new;
+	struct agp_memory *new;
 	void *addr;
 
 	if (pg_count != 1)
@@ -211,9 +211,9 @@
 	return new;
 }
 
-static agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
+static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type)
 {
-	agp_memory *new;
+	struct agp_memory *new;
 
 	if (type == AGP_DCACHE_MEMORY) {
 		if (pg_count != intel_i810_private.num_dcache_entries)
@@ -235,7 +235,7 @@
 	return NULL;
 }
 
-static void intel_i810_free_by_type(agp_memory * curr)
+static void intel_i810_free_by_type(struct agp_memory *curr)
 {
 	agp_free_key(curr->key);
 	if(curr->type == AGP_PHYS_MEMORY) {
@@ -434,7 +434,8 @@
 	iounmap((void *) intel_i830_private.registers);
 }
 
-static int intel_i830_insert_entries(agp_memory *mem,off_t pg_start,int type)
+static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start,
+				int type)
 {
 	int i,j,num_entries;
 	void *temp;
@@ -474,7 +475,8 @@
 	return(0);
 }
 
-static int intel_i830_remove_entries(agp_memory *mem,off_t pg_start,int type)
+static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
+				int type)
 {
 	int i;
 
@@ -495,7 +497,7 @@
 	return (0);
 }
 
-static agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
+static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
 {
 	if (type == AGP_PHYS_MEMORY)
 		return(alloc_agpphysmem_i8xx(pg_count, type));
@@ -562,14 +564,14 @@
 	return __intel_8xx_fetch_size(temp);
 }
 
-static void intel_tlbflush(agp_memory * mem)
+static void intel_tlbflush(struct agp_memory *mem)
 {
 	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);
 	pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
 }
 
 
-static void intel_8xx_tlbflush(agp_memory * mem)
+static void intel_8xx_tlbflush(struct agp_memory *mem)
 {
 	u32 temp;
 	pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
@@ -674,7 +676,7 @@
 	return 0;
 }
 
-static void intel_820_tlbflush(agp_memory * mem)
+static void intel_820_tlbflush(struct agp_memory *mem)
 {
 	return;
 }
diff -urN linux-2.5.69-bk15/drivers/char/agp/nvidia-agp.c linux-2.5.69-bk16/drivers/char/agp/nvidia-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/nvidia-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/nvidia-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -148,7 +148,7 @@
  */
 extern int agp_memory_reserved;
 
-static int nvidia_insert_memory(agp_memory * mem, off_t pg_start, int type)
+static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
 {
 	int i, j;
 	
@@ -176,7 +176,7 @@
 }
 
 
-static int nvidia_remove_memory(agp_memory * mem, off_t pg_start, int type)
+static int nvidia_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
 {
 	int i;
 
@@ -193,7 +193,7 @@
 }
 
 
-static void nvidia_tlbflush(agp_memory * mem)
+static void nvidia_tlbflush(struct agp_memory *mem)
 {
 	unsigned long end;
 	u32 wbc_reg, temp;
diff -urN linux-2.5.69-bk15/drivers/char/agp/sis-agp.c linux-2.5.69-bk16/drivers/char/agp/sis-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/sis-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/sis-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -33,7 +33,7 @@
 	return 0;
 }
 
-static void sis_tlbflush(agp_memory * mem)
+static void sis_tlbflush(struct agp_memory *mem)
 {
 	pci_write_config_byte(agp_bridge->dev, SIS_TLBFLUSH, 0x02);
 }
diff -urN linux-2.5.69-bk15/drivers/char/agp/sworks-agp.c linux-2.5.69-bk16/drivers/char/agp/sworks-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/sworks-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/sworks-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -231,7 +231,7 @@
  * more efficent, since agp_memory blocks can be a large number of
  * entries.
  */
-static void serverworks_tlbflush(agp_memory * temp)
+static void serverworks_tlbflush(struct agp_memory *temp)
 {
 	unsigned long end;
 
@@ -308,7 +308,7 @@
 	iounmap((void *) serverworks_private.registers);
 }
 
-static int serverworks_insert_memory(agp_memory * mem,
+static int serverworks_insert_memory(struct agp_memory *mem,
 			     off_t pg_start, int type)
 {
 	int i, j, num_entries;
@@ -349,7 +349,7 @@
 	return 0;
 }
 
-static int serverworks_remove_memory(agp_memory * mem, off_t pg_start,
+static int serverworks_remove_memory(struct agp_memory *mem, off_t pg_start,
 			     int type)
 {
 	int i;
diff -urN linux-2.5.69-bk15/drivers/char/agp/uninorth-agp.c linux-2.5.69-bk16/drivers/char/agp/uninorth-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/uninorth-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/uninorth-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -39,7 +39,7 @@
 	return 0;
 }
 
-static void uninorth_tlbflush(agp_memory * mem)
+static void uninorth_tlbflush(struct agp_memory *mem)
 {
 	pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
 			UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_INVAL);
@@ -89,7 +89,8 @@
 	return 0;
 }
 
-static int uninorth_insert_memory(agp_memory * mem, off_t pg_start, int type)
+static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start,
+				int type)
 {
 	int i, j, num_entries;
 	void *temp;
@@ -280,8 +281,6 @@
 	.free_by_type		= agp_generic_free_by_type,
 	.agp_alloc_page		= agp_generic_alloc_page,
 	.agp_destroy_page	= agp_generic_destroy_page,
-	.suspend		= agp_generic_suspend,
-	.resume			= agp_generic_resume,
 	.cant_use_aperture	= 1,
 };
 
diff -urN linux-2.5.69-bk15/drivers/char/agp/via-agp.c linux-2.5.69-bk16/drivers/char/agp/via-agp.c
--- linux-2.5.69-bk15/drivers/char/agp/via-agp.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/agp/via-agp.c	2003-05-23 04:36:21.000000000 -0700
@@ -68,7 +68,7 @@
 }
 
 
-static void via_tlbflush(agp_memory * mem)
+static void via_tlbflush(struct agp_memory *mem)
 {
 	pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000008f);
 	pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000000f);
@@ -136,7 +136,7 @@
 }
 
 
-static void via_tlbflush_agp3(agp_memory * mem)
+static void via_tlbflush_agp3(struct agp_memory *mem)
 {
 	u32 temp;
 
diff -urN linux-2.5.69-bk15/drivers/char/drm/drmP.h linux-2.5.69-bk16/drivers/char/drm/drmP.h
--- linux-2.5.69-bk15/drivers/char/drm/drmP.h	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/drm/drmP.h	2003-05-23 04:36:21.000000000 -0700
@@ -444,7 +444,7 @@
 #if __REALLY_HAVE_AGP
 typedef struct drm_agp_mem {
 	unsigned long      handle;
-	agp_memory         *memory;
+	struct agp_memory         *memory;
 	unsigned long      bound; /* address */
 	int                pages;
 	struct drm_agp_mem *prev;
@@ -452,7 +452,7 @@
 } drm_agp_mem_t;
 
 typedef struct drm_agp_head {
-	agp_kern_info      agp_info;
+	struct agp_kern_info      agp_info;
 	drm_agp_mem_t      *memory;
 	unsigned long      mode;
 	int                enabled;
@@ -657,10 +657,10 @@
 extern void	     DRM(ioremapfree)(void *pt, unsigned long size);
 
 #if __REALLY_HAVE_AGP
-extern agp_memory    *DRM(alloc_agp)(int pages, u32 type);
-extern int           DRM(free_agp)(agp_memory *handle, int pages);
-extern int           DRM(bind_agp)(agp_memory *handle, unsigned int start);
-extern int           DRM(unbind_agp)(agp_memory *handle);
+extern struct agp_memory    *DRM(alloc_agp)(int pages, u32 type);
+extern int           DRM(free_agp)(struct agp_memory *handle, int pages);
+extern int           DRM(bind_agp)(struct agp_memory *handle, unsigned int start);
+extern int           DRM(unbind_agp)(struct agp_memory *handle);
 #endif
 
 				/* Misc. IOCTL support (drm_ioctl.h) */
@@ -804,10 +804,10 @@
 				      unsigned int cmd, unsigned long arg);
 extern int            DRM(agp_bind)(struct inode *inode, struct file *filp,
 				    unsigned int cmd, unsigned long arg);
-extern agp_memory     *DRM(agp_allocate_memory)(size_t pages, u32 type);
-extern int            DRM(agp_free_memory)(agp_memory *handle);
-extern int            DRM(agp_bind_memory)(agp_memory *handle, off_t start);
-extern int            DRM(agp_unbind_memory)(agp_memory *handle);
+extern struct agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type);
+extern int            DRM(agp_free_memory)(struct agp_memory *handle);
+extern int            DRM(agp_bind_memory)(struct agp_memory *handle, off_t start);
+extern int            DRM(agp_unbind_memory)(struct agp_memory *handle);
 #endif
 
 				/* Stub support (drm_stub.h) */
diff -urN linux-2.5.69-bk15/drivers/char/drm/drm_agpsupport.h linux-2.5.69-bk16/drivers/char/drm/drm_agpsupport.h
--- linux-2.5.69-bk15/drivers/char/drm/drm_agpsupport.h	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/drm/drm_agpsupport.h	2003-05-23 04:36:21.000000000 -0700
@@ -44,7 +44,7 @@
 {
 	drm_file_t	 *priv	 = filp->private_data;
 	drm_device_t	 *dev	 = priv->dev;
-	agp_kern_info    *kern;
+	struct agp_kern_info *kern;
 	drm_agp_info_t   info;
 
 	if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
@@ -126,7 +126,7 @@
 	drm_device_t	 *dev	 = priv->dev;
 	drm_agp_buffer_t request;
 	drm_agp_mem_t    *entry;
-	agp_memory       *memory;
+	struct agp_memory *memory;
 	unsigned long    pages;
 	u32 		 type;
 
@@ -280,26 +280,26 @@
 	drm_agp = NULL;
 }
 
-agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type)
+struct agp_memory *DRM(agp_allocate_memory)(size_t pages, u32 type)
 {
 	if (!drm_agp->allocate_memory) return NULL;
 	return drm_agp->allocate_memory(pages, type);
 }
 
-int DRM(agp_free_memory)(agp_memory *handle)
+int DRM(agp_free_memory)(struct agp_memory *handle)
 {
 	if (!handle || !drm_agp->free_memory) return 0;
 	drm_agp->free_memory(handle);
 	return 1;
 }
 
-int DRM(agp_bind_memory)(agp_memory *handle, off_t start)
+int DRM(agp_bind_memory)(struct agp_memory *handle, off_t start)
 {
 	if (!handle || !drm_agp->bind_memory) return -EINVAL;
 	return drm_agp->bind_memory(handle, start);
 }
 
-int DRM(agp_unbind_memory)(agp_memory *handle)
+int DRM(agp_unbind_memory)(struct agp_memory *handle)
 {
 	if (!handle || !drm_agp->unbind_memory) return -EINVAL;
 	return drm_agp->unbind_memory(handle);
diff -urN linux-2.5.69-bk15/drivers/char/drm/drm_memory.h linux-2.5.69-bk16/drivers/char/drm/drm_memory.h
--- linux-2.5.69-bk15/drivers/char/drm/drm_memory.h	2003-05-04 16:53:03.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/drm/drm_memory.h	2003-05-23 04:36:21.000000000 -0700
@@ -134,22 +134,22 @@
 }
 
 #if __REALLY_HAVE_AGP
-agp_memory *DRM(alloc_agp)(int pages, u32 type)
+struct agp_memory *DRM(alloc_agp)(int pages, u32 type)
 {
 	return DRM(agp_allocate_memory)(pages, type);
 }
 
-int DRM(free_agp)(agp_memory *handle, int pages)
+int DRM(free_agp)(struct agp_memory *handle, int pages)
 {
 	return DRM(agp_free_memory)(handle) ? 0 : -EINVAL;
 }
 
-int DRM(bind_agp)(agp_memory *handle, unsigned int start)
+int DRM(bind_agp)(struct agp_memory *handle, unsigned int start)
 {
 	return DRM(agp_bind_memory)(handle, start);
 }
 
-int DRM(unbind_agp)(agp_memory *handle)
+int DRM(unbind_agp)(struct agp_memory *handle)
 {
 	return DRM(agp_unbind_memory)(handle);
 }
diff -urN linux-2.5.69-bk15/drivers/char/i8k.c linux-2.5.69-bk16/drivers/char/i8k.c
--- linux-2.5.69-bk15/drivers/char/i8k.c	2003-05-04 16:53:07.000000000 -0700
+++ linux-2.5.69-bk16/drivers/char/i8k.c	2003-05-23 04:36:21.000000000 -0700
@@ -757,7 +757,7 @@
 	return -ENOENT;
     }
     proc_i8k->proc_fops = &i8k_fops;
-    SET_MODULE_OWNER(proc_i8k);
+    proc_i8k->owner = THIS_MODULE;
 
     printk(KERN_INFO
 	   "Dell laptop SMM driver v%s Massimo Dal Zotto (dz@debian.org)\n",
diff -urN linux-2.5.69-bk15/drivers/isdn/act2000/module.c linux-2.5.69-bk16/drivers/isdn/act2000/module.c
--- linux-2.5.69-bk15/drivers/isdn/act2000/module.c	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/act2000/module.c	2003-05-23 04:36:21.000000000 -0700
@@ -587,7 +587,7 @@
 	INIT_WORK(&card->rcv_tq, (void *) (void *) actcapi_dispatch, card);
 	INIT_WORK(&card->poll_tq, (void *) (void *) act2000_receive, card);
 	init_timer(&card->ptimer);
-	SET_MODULE_OWNER(&card->interface);
+	card->interface.owner = THIS_MODULE;
         card->interface.channels = ACT2000_BCH;
         card->interface.maxbufsize = 4000;
         card->interface.command = if_command;
diff -urN linux-2.5.69-bk15/drivers/isdn/eicon/eicon_mod.c linux-2.5.69-bk16/drivers/isdn/eicon/eicon_mod.c
--- linux-2.5.69-bk15/drivers/isdn/eicon/eicon_mod.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/eicon/eicon_mod.c	2003-05-23 04:36:21.000000000 -0700
@@ -834,7 +834,7 @@
 		tasklet_init(&card->snd_tq, eicon_transmit, (unsigned long)card);
 		tasklet_init(&card->rcv_tq, eicon_rcv_dispatch, (unsigned long)card);
 		tasklet_init(&card->ack_tq, eicon_ack_dispatch, (unsigned long)card);
-		SET_MODULE_OWNER(&card->interface);
+		card->interface.owner = THIS_MODULE;
 		card->interface.maxbufsize = 4000;
 		card->interface.command = if_command;
 		card->interface.writebuf_skb = if_sendbuf;
diff -urN linux-2.5.69-bk15/drivers/isdn/hardware/avm/b1isa.c linux-2.5.69-bk16/drivers/isdn/hardware/avm/b1isa.c
--- linux-2.5.69-bk15/drivers/isdn/hardware/avm/b1isa.c	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hardware/avm/b1isa.c	2003-05-23 04:36:21.000000000 -0700
@@ -118,7 +118,7 @@
 	cinfo->capi_ctrl.procinfo      = b1isa_procinfo;
 	cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
 	strcpy(cinfo->capi_ctrl.name, card->name);
-	SET_MODULE_OWNER(&cinfo->capi_ctrl);
+	cinfo->capi_ctrl.owner = THIS_MODULE;
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
 	if (retval) {
diff -urN linux-2.5.69-bk15/drivers/isdn/hardware/avm/b1pci.c linux-2.5.69-bk16/drivers/isdn/hardware/avm/b1pci.c
--- linux-2.5.69-bk15/drivers/isdn/hardware/avm/b1pci.c	2003-05-04 16:52:49.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hardware/avm/b1pci.c	2003-05-23 04:36:21.000000000 -0700
@@ -111,7 +111,7 @@
 	cinfo->capi_ctrl.procinfo      = b1pci_procinfo;
 	cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
 	strcpy(cinfo->capi_ctrl.name, card->name);
-	SET_MODULE_OWNER(&cinfo->capi_ctrl);
+	cinfo->capi_ctrl.owner = THIS_MODULE;
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
 	if (retval) {
@@ -249,7 +249,7 @@
 	cinfo->capi_ctrl.procinfo      = b1pciv4_procinfo;
 	cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
 	strcpy(cinfo->capi_ctrl.name, card->name);
-	SET_MODULE_OWNER(&cinfo->capi_ctrl);
+	cinfo->capi_ctrl.owner = THIS_MODULE;
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
 	if (retval) {
diff -urN linux-2.5.69-bk15/drivers/isdn/hardware/avm/b1pcmcia.c linux-2.5.69-bk16/drivers/isdn/hardware/avm/b1pcmcia.c
--- linux-2.5.69-bk15/drivers/isdn/hardware/avm/b1pcmcia.c	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hardware/avm/b1pcmcia.c	2003-05-23 04:36:21.000000000 -0700
@@ -105,7 +105,7 @@
 	cinfo->capi_ctrl.procinfo      = b1pcmcia_procinfo;
 	cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
 	strcpy(cinfo->capi_ctrl.name, card->name);
-	SET_MODULE_OWNER(&cinfo->capi_ctrl);
+	cinfo->capi_ctrl.owner = THIS_MODULE;
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
 	if (retval) {
diff -urN linux-2.5.69-bk15/drivers/isdn/hardware/avm/c4.c linux-2.5.69-bk16/drivers/isdn/hardware/avm/c4.c
--- linux-2.5.69-bk15/drivers/isdn/hardware/avm/c4.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hardware/avm/c4.c	2003-05-23 04:36:21.000000000 -0700
@@ -1166,7 +1166,7 @@
 		cinfo->capi_ctrl.procinfo      = c4_procinfo;
 		cinfo->capi_ctrl.ctr_read_proc = c4_read_proc;
 		strcpy(cinfo->capi_ctrl.name, card->name);
-		SET_MODULE_OWNER(&cinfo->capi_ctrl);
+		cinfo->capi_ctrl.owner = THIS_MODULE;
 
 		retval = attach_capi_ctr(&cinfo->capi_ctrl);
 		if (retval) {
diff -urN linux-2.5.69-bk15/drivers/isdn/hardware/avm/t1isa.c linux-2.5.69-bk16/drivers/isdn/hardware/avm/t1isa.c
--- linux-2.5.69-bk15/drivers/isdn/hardware/avm/t1isa.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hardware/avm/t1isa.c	2003-05-23 04:36:21.000000000 -0700
@@ -411,7 +411,7 @@
 	cinfo->capi_ctrl.procinfo      = t1isa_procinfo;
 	cinfo->capi_ctrl.ctr_read_proc = b1ctl_read_proc;
 	strcpy(cinfo->capi_ctrl.name, card->name);
-	SET_MODULE_OWNER(&cinfo->capi_ctrl);
+	cinfo->capi_ctrl.owner = THIS_MODULE;
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
 	if (retval) {
diff -urN linux-2.5.69-bk15/drivers/isdn/hardware/avm/t1pci.c linux-2.5.69-bk16/drivers/isdn/hardware/avm/t1pci.c
--- linux-2.5.69-bk15/drivers/isdn/hardware/avm/t1pci.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hardware/avm/t1pci.c	2003-05-23 04:36:21.000000000 -0700
@@ -119,7 +119,7 @@
 	cinfo->capi_ctrl.procinfo      = t1pci_procinfo;
 	cinfo->capi_ctrl.ctr_read_proc = b1dmactl_read_proc;
 	strcpy(cinfo->capi_ctrl.name, card->name);
-	SET_MODULE_OWNER(&cinfo->capi_ctrl);
+	cinfo->capi_ctrl.owner = THIS_MODULE;
 
 	retval = attach_capi_ctr(&cinfo->capi_ctrl);
 	if (retval) {
diff -urN linux-2.5.69-bk15/drivers/isdn/hardware/eicon/capimain.c linux-2.5.69-bk16/drivers/isdn/hardware/eicon/capimain.c
--- linux-2.5.69-bk15/drivers/isdn/hardware/eicon/capimain.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hardware/eicon/capimain.c	2003-05-23 04:36:21.000000000 -0700
@@ -149,7 +149,7 @@
 	ctrl->load_firmware = 0;
 	ctrl->reset_ctr = 0;
 	ctrl->ctr_read_proc = diva_ctl_read_proc;
-	SET_MODULE_OWNER(ctrl);
+	ctrl->owner = THIS_MODULE;
 }
 
 /*
diff -urN linux-2.5.69-bk15/drivers/isdn/hardware/eicon/i4lididrv.c linux-2.5.69-bk16/drivers/isdn/hardware/eicon/i4lididrv.c
--- linux-2.5.69-bk15/drivers/isdn/hardware/eicon/i4lididrv.c	2003-05-04 16:53:42.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hardware/eicon/i4lididrv.c	2003-05-23 04:36:21.000000000 -0700
@@ -913,7 +913,7 @@
 	skb_queue_head_init(&card->sackq);
 	skb_queue_head_init(&card->statq);
 	card->statq_entries = 0;
-	SET_MODULE_OWNER(&card->interface);
+	card->interface.owner = THIS_MODULE;
 	card->interface.maxbufsize = 4000;
 	card->interface.command = if_command;
 	card->interface.writebuf_skb = if_sendbuf;
diff -urN linux-2.5.69-bk15/drivers/isdn/hisax/config.c linux-2.5.69-bk16/drivers/isdn/hisax/config.c
--- linux-2.5.69-bk15/drivers/isdn/hisax/config.c	2003-05-04 16:53:40.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hisax/config.c	2003-05-23 04:36:21.000000000 -0700
@@ -889,7 +889,7 @@
 		       "HiSax: Card Type %d out of range\n", card->typ);
 		goto outf_cs;
 	}
-	SET_MODULE_OWNER(&cs->iif);
+	cs->iif.owner = THIS_MODULE;
 	strcpy(cs->iif.id, id);
 	cs->iif.channels = 2;
 	cs->iif.maxbufsize = MAX_DATA_SIZE;
diff -urN linux-2.5.69-bk15/drivers/isdn/hisax/hisax_fcclassic.c linux-2.5.69-bk16/drivers/isdn/hisax/hisax_fcclassic.c
--- linux-2.5.69-bk15/drivers/isdn/hisax/hisax_fcclassic.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hisax/hisax_fcclassic.c	2003-05-23 04:36:21.000000000 -0700
@@ -293,7 +293,7 @@
 
 	memset(adapter, 0, sizeof(struct fritz_adapter));
 
-	SET_MODULE_OWNER(&adapter->isac.hisax_d_if);
+	adapter->isac.hisax_d_if.owner = THIS_MODULE;
 	adapter->isac.hisax_d_if.ifc.priv = &adapter->isac;
 	adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1;
 
diff -urN linux-2.5.69-bk15/drivers/isdn/hisax/hisax_fcpcipnp.c linux-2.5.69-bk16/drivers/isdn/hisax/hisax_fcpcipnp.c
--- linux-2.5.69-bk15/drivers/isdn/hisax/hisax_fcpcipnp.c	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hisax/hisax_fcpcipnp.c	2003-05-23 04:36:21.000000000 -0700
@@ -827,7 +827,7 @@
 
 	memset(adapter, 0, sizeof(struct fritz_adapter));
 
-	SET_MODULE_OWNER(&adapter->isac.hisax_d_if);
+	adapter->isac.hisax_d_if.owner = THIS_MODULE;
 	adapter->isac.hisax_d_if.ifc.priv = &adapter->isac;
 	adapter->isac.hisax_d_if.ifc.l2l1 = isac_d_l2l1;
 	
diff -urN linux-2.5.69-bk15/drivers/isdn/hisax/hisax_hfcpci.c linux-2.5.69-bk16/drivers/isdn/hisax/hisax_hfcpci.c
--- linux-2.5.69-bk15/drivers/isdn/hisax/hisax_hfcpci.c	2003-05-04 16:53:09.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hisax/hisax_hfcpci.c	2003-05-23 04:36:21.000000000 -0700
@@ -1484,7 +1484,7 @@
 
 	memset(adapter, 0, sizeof(struct hfcpci_adapter));
 
-	SET_MODULE_OWNER(&adapter->d_if);
+	adapter->d_if.owner = THIS_MODULE;
 	adapter->d_if.ifc.priv = adapter;
 	adapter->d_if.ifc.l2l1 = hfcpci_d_l2l1;
 	
diff -urN linux-2.5.69-bk15/drivers/isdn/hisax/st5481_init.c linux-2.5.69-bk16/drivers/isdn/hisax/st5481_init.c
--- linux-2.5.69-bk15/drivers/isdn/hisax/st5481_init.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hisax/st5481_init.c	2003-05-23 04:36:21.000000000 -0700
@@ -80,7 +80,7 @@
 	adapter->number_of_leds = number_of_leds;
 	adapter->usb_dev = dev;
 
-	SET_MODULE_OWNER(&adapter->hisax_d_if);
+	adapter->hisax_d_if.owner = THIS_MODULE;
 	adapter->hisax_d_if.ifc.priv = adapter;
 	adapter->hisax_d_if.ifc.l2l1 = st5481_d_l2l1;
 
diff -urN linux-2.5.69-bk15/drivers/isdn/hysdn/hycapi.c linux-2.5.69-bk16/drivers/isdn/hysdn/hycapi.c
--- linux-2.5.69-bk15/drivers/isdn/hysdn/hycapi.c	2003-05-04 16:53:01.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/hysdn/hycapi.c	2003-05-23 04:36:21.000000000 -0700
@@ -778,7 +778,7 @@
 		ctrl->procinfo      = hycapi_procinfo;
 		ctrl->ctr_read_proc = hycapi_read_proc;
 		strcpy(ctrl->name, cinfo->cardname);
-		SET_MODULE_OWNER(ctrl);
+		ctrl->owner = THIS_MODULE;
 
 		retval = attach_capi_ctr(ctrl);
 		if (retval) {
diff -urN linux-2.5.69-bk15/drivers/isdn/icn/icn.c linux-2.5.69-bk16/drivers/isdn/icn/icn.c
--- linux-2.5.69-bk15/drivers/isdn/icn/icn.c	2003-05-04 16:53:57.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/icn/icn.c	2003-05-23 04:36:21.000000000 -0700
@@ -1545,7 +1545,7 @@
 	}
 	memset((char *) card, 0, sizeof(icn_card));
 	card->port = port;
-	SET_MODULE_OWNER(&card->interface);
+	card->interface.owner = THIS_MODULE;
 	card->interface.hl_hdrlen = 1;
 	card->interface.channels = ICN_BCH;
 	card->interface.maxbufsize = 4000;
diff -urN linux-2.5.69-bk15/drivers/isdn/isdnloop/isdnloop.c linux-2.5.69-bk16/drivers/isdn/isdnloop/isdnloop.c
--- linux-2.5.69-bk15/drivers/isdn/isdnloop/isdnloop.c	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/isdnloop/isdnloop.c	2003-05-23 04:36:21.000000000 -0700
@@ -1450,7 +1450,7 @@
 		return (isdnloop_card *) 0;
 	}
 	memset((char *) card, 0, sizeof(isdnloop_card));
-	SET_MODULE_OWNER(&card->interface);
+	card->interface.owner = THIS_MODULE;
 	card->interface.channels = ISDNLOOP_BCH;
 	card->interface.hl_hdrlen  = 1; /* scratch area for storing ack flag*/ 
 	card->interface.maxbufsize = 4000;
diff -urN linux-2.5.69-bk15/drivers/isdn/pcbit/drv.c linux-2.5.69-bk16/drivers/isdn/pcbit/drv.c
--- linux-2.5.69-bk15/drivers/isdn/pcbit/drv.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/pcbit/drv.c	2003-05-23 04:36:21.000000000 -0700
@@ -171,7 +171,7 @@
 
 	dev->dev_if = dev_if;
 
-	SET_MODULE_OWNER(dev_if);
+	dev_if->owner = THIS_MODULE;
 
 	dev_if->channels = 2;
 	
diff -urN linux-2.5.69-bk15/drivers/isdn/sc/init.c linux-2.5.69-bk16/drivers/isdn/sc/init.c
--- linux-2.5.69-bk15/drivers/isdn/sc/init.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/sc/init.c	2003-05-23 04:36:21.000000000 -0700
@@ -287,7 +287,7 @@
 		}
 		memset(interface, 0, sizeof(isdn_if));
 
-		SET_MODULE_OWNER(interface);
+		interface->owner = THIS_MODULE;
 		interface->hl_hdrlen = 0;
 		interface->channels = channels;
 		interface->maxbufsize = BUFFER_SIZE;
diff -urN linux-2.5.69-bk15/drivers/isdn/tpam/tpam_main.c linux-2.5.69-bk16/drivers/isdn/tpam/tpam_main.c
--- linux-2.5.69-bk15/drivers/isdn/tpam/tpam_main.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk16/drivers/isdn/tpam/tpam_main.c	2003-05-23 04:36:21.000000000 -0700
@@ -132,7 +132,7 @@
 	copy_to_pam_dword(card, (void *)0x01840070, 0x00000010);
 
 	/* fill the ISDN link layer structure */
-	SET_MODULE_OWNER(&card->interface);
+	card->interface.owner = THIS_MODULE;
 	card->interface.channels = TPAM_NBCHANNEL;
 	card->interface.maxbufsize = TPAM_MAXBUFSIZE;
 	card->interface.features = 
diff -urN linux-2.5.69-bk15/drivers/macintosh/apm_emu.c linux-2.5.69-bk16/drivers/macintosh/apm_emu.c
--- linux-2.5.69-bk15/drivers/macintosh/apm_emu.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk16/drivers/macintosh/apm_emu.c	2003-05-23 04:36:21.000000000 -0700
@@ -524,7 +524,7 @@
 		
 	apm_proc = create_proc_info_entry("apm", 0, NULL, apm_emu_get_info);
 	if (apm_proc)
-		SET_MODULE_OWNER(apm_proc);
+		apm_proc->owner = THIS_MODULE;
 
 	misc_register(&apm_device);
 
diff -urN linux-2.5.69-bk15/drivers/net/arcnet/arc-rawmode.c linux-2.5.69-bk16/drivers/net/arcnet/arc-rawmode.c
--- linux-2.5.69-bk15/drivers/net/arcnet/arc-rawmode.c	2003-05-04 16:53:42.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/arcnet/arc-rawmode.c	2003-05-23 04:36:21.000000000 -0700
@@ -53,10 +53,12 @@
 };
 
 
-void arcnet_raw_init(void)
+static int __init arcnet_raw_init(void)
 {
 	int count;
 
+	printk(VERSION);
+
 	for (count = 0; count < 256; count++)
 		if (arc_proto_map[count] == arc_proto_default)
 			arc_proto_map[count] = &rawmode_proto;
@@ -66,26 +68,18 @@
 		arc_bcast_proto = &rawmode_proto;
 
 	arc_proto_default = &rawmode_proto;
-}
-
-
-#ifdef MODULE
-
-int __init init_module(void)
-{
-	printk(VERSION);
-	arcnet_raw_init();
 	return 0;
 }
 
-void cleanup_module(void)
+static void __exit arcnet_raw_exit(void)
 {
 	arcnet_unregister_proto(&rawmode_proto);
 }
 
-MODULE_LICENSE("GPL");
-#endif				/* MODULE */
+module_init(arcnet_raw_init);
+module_exit(arcnet_raw_exit);
 
+MODULE_LICENSE("GPL");
 
 
 /* packet receiver */
diff -urN linux-2.5.69-bk15/drivers/net/arcnet/arcnet.c linux-2.5.69-bk16/drivers/net/arcnet/arcnet.c
--- linux-2.5.69-bk15/drivers/net/arcnet/arcnet.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/arcnet/arcnet.c	2003-05-23 04:36:21.000000000 -0700
@@ -106,13 +106,15 @@
 static struct net_device_stats *arcnet_get_stats(struct net_device *dev);
 static int go_tx(struct net_device *dev);
 
-void __init arcnet_init(void)
+static int debug = ARCNET_DEBUG;
+MODULE_PARM(debug, "i");
+MODULE_LICENSE("GPL");
+
+static int __init arcnet_init(void)
 {
-	static int arcnet_inited;
 	int count;
 
-	if (arcnet_inited++)
-		return;
+	arcnet_debug = debug;
 
 	printk(VERSION);
 
@@ -138,47 +140,15 @@
 		sizeof(struct arc_rfc1051), sizeof(struct arc_eth_encap),
 		   sizeof(struct archdr));
 
-#ifdef CONFIG_ARCNET		/* We're not built as a module */
-	printk("arcnet: Available protocols:");
-#ifdef CONFIG_ARCNET_1201
-	printk(" RFC1201");
-	arcnet_rfc1201_init();
-#endif
-#ifdef CONFIG_ARCNET_1051
-	printk(" RFC1051");
-	arcnet_rfc1051_init();
-#endif
-#ifdef CONFIG_ARCNET_RAW
-	printk(" RAW");
-	arcnet_raw_init();
-#endif
-	printk("\n");
-#ifdef CONFIG_ARCNET_COM90xx
-	com90xx_probe(NULL);
-#endif
-#endif
-}
-
-
-#ifdef MODULE
-
-static int debug = ARCNET_DEBUG;
-MODULE_PARM(debug, "i");
-MODULE_LICENSE("GPL");
-
-int __init init_module(void)
-{
-	arcnet_debug = debug;
-	arcnet_init();
 	return 0;
 }
 
-void cleanup_module(void)
+static void __exit arcnet_exit(void)
 {
 }
 
-#endif
-
+module_init(arcnet_init);
+module_exit(arcnet_exit);
 
 /*
  * Dump the contents of an sk_buff
diff -urN linux-2.5.69-bk15/drivers/net/arcnet/com20020-isa.c linux-2.5.69-bk16/drivers/net/arcnet/com20020-isa.c
--- linux-2.5.69-bk15/drivers/net/arcnet/com20020-isa.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/arcnet/com20020-isa.c	2003-05-23 04:36:21.000000000 -0700
@@ -54,10 +54,6 @@
 	unsigned long airqmask;
 	struct arcnet_local *lp = dev->priv;
 
-#ifndef MODULE
-	arcnet_init();
-#endif
-
 	BUGLVL(D_NORMAL) printk(VERSION);
 
 	ioaddr = dev->base_addr;
diff -urN linux-2.5.69-bk15/drivers/net/arcnet/com20020-pci.c linux-2.5.69-bk16/drivers/net/arcnet/com20020-pci.c
--- linux-2.5.69-bk15/drivers/net/arcnet/com20020-pci.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/arcnet/com20020-pci.c	2003-05-23 04:36:21.000000000 -0700
@@ -183,9 +183,6 @@
 static int __init com20020pci_init(void)
 {
 	BUGLVL(D_NORMAL) printk(VERSION);
-#ifndef MODULE
-	arcnet_init();
-#endif
 	return pci_module_init(&com20020pci_driver);
 }
 
diff -urN linux-2.5.69-bk15/drivers/net/arcnet/com90io.c linux-2.5.69-bk16/drivers/net/arcnet/com90io.c
--- linux-2.5.69-bk15/drivers/net/arcnet/com90io.c	2003-05-04 16:53:09.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/arcnet/com90io.c	2003-05-23 04:36:21.000000000 -0700
@@ -151,10 +151,6 @@
 	int ioaddr = dev->base_addr, status;
 	unsigned long airqmask;
 
-#ifndef MODULE
-	arcnet_init();
-#endif
-
 	BUGLVL(D_NORMAL) printk(VERSION);
 	BUGLVL(D_NORMAL) printk("E-mail me if you actually test this driver, please!\n");
 
diff -urN linux-2.5.69-bk15/drivers/net/arcnet/com90xx.c linux-2.5.69-bk16/drivers/net/arcnet/com90xx.c
--- linux-2.5.69-bk15/drivers/net/arcnet/com90xx.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/arcnet/com90xx.c	2003-05-23 04:36:21.000000000 -0700
@@ -29,7 +29,6 @@
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/netdevice.h>
-#include <linux/bootmem.h>
 #include <asm/io.h>
 #include <linux/arcdevice.h>
 
@@ -100,7 +99,7 @@
 
 static int com90xx_skip_probe __initdata = 0;
 
-int __init com90xx_probe(struct net_device *dev)
+static int __init com90xx_probe(struct net_device *dev)
 {
 	int count, status, ioaddr, numprint, airq, retval = -ENODEV,
 	 openparen = 0;
@@ -115,10 +114,6 @@
 	if (!dev && com90xx_skip_probe)
 		return -ENODEV;
 
-#ifndef MODULE
-	arcnet_init();
-#endif
-
 	BUGLVL(D_NORMAL) printk(VERSION);
 
 	/* set up the arrays where we'll store the possible probe addresses */
@@ -603,9 +598,6 @@
 }
 
 
-
-#ifdef MODULE
-
 /* Module parameters */
 
 static int io;			/* use the insmod io= irq= shmem= options */
@@ -619,7 +611,7 @@
 MODULE_PARM(device, "s");
 MODULE_LICENSE("GPL");
 
-int init_module(void)
+static int __init com90xx_init(void)
 {
 	struct net_device *dev;
 	int err;
@@ -642,8 +634,7 @@
 	return 0;
 }
 
-
-void cleanup_module(void)
+static void __exit com90xx_exit(void)
 {
 	struct net_device *dev;
 	struct arcnet_local *lp;
@@ -663,44 +654,38 @@
 	}
 }
 
-#else
+module_init(com90xx_init);
+module_exit(com90xx_exit);
 
+#ifndef MODULE
 static int __init com90xx_setup(char *s)
 {
-	struct net_device *dev;
 	int ints[8];
 
-	com90xx_skip_probe = 1;
-
 	s = get_options(s, 8, ints);
 	if (!ints[0] && !*s) {
 		printk("com90xx: Disabled.\n");
 		return 1;
 	}
-	dev = alloc_bootmem(sizeof(struct net_device));
-	memset(dev, 0, sizeof(struct net_device));
-	dev->init = com90xx_probe;
 
 	switch (ints[0]) {
 	default:		/* ERROR */
 		printk("com90xx: Too many arguments.\n");
 	case 3:		/* Mem address */
-		dev->mem_start = ints[3];
+		shmem = ints[3];
 	case 2:		/* IRQ */
-		dev->irq = ints[2];
+		irq = ints[2];
 	case 1:		/* IO address */
-		dev->base_addr = ints[1];
+		io = ints[1];
 	}
+
 	if (*s)
-		strncpy(dev->name, s, 9);
+		strncpy(device, s, 9);
 	else
-		strcpy(dev->name, "arc%d");
-	if (register_netdev(dev))
-		printk(KERN_ERR "com90xx: Cannot register arcnet device\n");
+		strcpy(device, "arc%d");
 
 	return 1;
 }
 
 __setup("com90xx=", com90xx_setup);
-
-#endif				/* MODULE */
+#endif
diff -urN linux-2.5.69-bk15/drivers/net/arcnet/rfc1051.c linux-2.5.69-bk16/drivers/net/arcnet/rfc1051.c
--- linux-2.5.69-bk15/drivers/net/arcnet/rfc1051.c	2003-05-04 16:53:33.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/arcnet/rfc1051.c	2003-05-23 04:36:21.000000000 -0700
@@ -53,8 +53,10 @@
 };
 
 
-void __init arcnet_rfc1051_init(void)
+static int __init arcnet_rfc1051_init(void)
 {
+	printk(VERSION);
+
 	arc_proto_map[ARC_P_IP_RFC1051]
 	    = arc_proto_map[ARC_P_ARP_RFC1051]
 	    = &rfc1051_proto;
@@ -63,27 +65,18 @@
 	if (arc_bcast_proto == arc_proto_default)
 		arc_bcast_proto = &rfc1051_proto;
 
-}
-
-
-#ifdef MODULE
-
-MODULE_LICENSE("GPL");
-
-int __init init_module(void)
-{
-	printk(VERSION);
-	arcnet_rfc1051_init();
 	return 0;
 }
 
-void cleanup_module(void)
+static void __exit arcnet_rfc1051_exit(void)
 {
 	arcnet_unregister_proto(&rfc1051_proto);
 }
 
-#endif				/* MODULE */
+module_init(arcnet_rfc1051_init);
+module_exit(arcnet_rfc1051_exit);
 
+MODULE_LICENSE("GPL");
 
 /*
  * Determine a packet's protocol ID.
diff -urN linux-2.5.69-bk15/drivers/net/arcnet/rfc1201.c linux-2.5.69-bk16/drivers/net/arcnet/rfc1201.c
--- linux-2.5.69-bk15/drivers/net/arcnet/rfc1201.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/arcnet/rfc1201.c	2003-05-23 04:36:21.000000000 -0700
@@ -53,8 +53,10 @@
 };
 
 
-void __init arcnet_rfc1201_init(void)
+static int __init arcnet_rfc1201_init(void)
 {
+	printk(VERSION);
+
 	arc_proto_map[ARC_P_IP]
 	    = arc_proto_map[ARC_P_IPV6]
 	    = arc_proto_map[ARC_P_ARP]
@@ -66,27 +68,17 @@
 	/* if someone else already owns the broadcast, we won't take it */
 	if (arc_bcast_proto == arc_proto_default)
 		arc_bcast_proto = &rfc1201_proto;
-}
-
-
-#ifdef MODULE
 
-MODULE_LICENSE("GPL");
-
-int __init init_module(void)
-{
-	printk(VERSION);
-	arcnet_rfc1201_init();
 	return 0;
 }
 
-void cleanup_module(void)
+static void __exit arcnet_rfc1201_exit(void)
 {
 	arcnet_unregister_proto(&rfc1201_proto);
 }
 
-#endif				/* MODULE */
-
+module_init(arcnet_rfc1201_init);
+module_exit(arcnet_rfc1201_exit);
 
 /*
  * Determine a packet's protocol ID.
diff -urN linux-2.5.69-bk15/drivers/net/setup.c linux-2.5.69-bk16/drivers/net/setup.c
--- linux-2.5.69-bk15/drivers/net/setup.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/setup.c	2003-05-23 04:36:21.000000000 -0700
@@ -11,7 +11,6 @@
 
 extern int dmascc_init(void);
 
-extern int arcnet_init(void); 
 extern int scc_enet_init(void); 
 extern int fec_enet_init(void); 
 extern int sdla_setup(void); 
@@ -42,9 +41,6 @@
 #if defined(CONFIG_SDLA)
 	{sdla_c_setup, 0},
 #endif
-#if defined(CONFIG_ARCNET)
-	{arcnet_init, 0},
-#endif
 #if defined(CONFIG_SCC_ENET)
         {scc_enet_init, 0},
 #endif
diff -urN linux-2.5.69-bk15/drivers/net/wan/comx-hw-munich.c linux-2.5.69-bk16/drivers/net/wan/comx-hw-munich.c
--- linux-2.5.69-bk15/drivers/net/wan/comx-hw-munich.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/wan/comx-hw-munich.c	2003-05-23 04:36:21.000000000 -0700
@@ -858,7 +858,7 @@
 		board->linecode = SLICECOM_LINECODE_DEFAULT;
 		board->clock_source = SLICECOM_CLOCK_SOURCE_DEFAULT;
 		board->loopback = SLICECOM_LOOPBACK_DEFAULT;
-		SET_MODULE_OWNER(board);
+		board->owner = THIS_MODULE;
 	    }
 	    else
 	    {
diff -urN linux-2.5.69-bk15/drivers/net/wan/cycx_x25.c linux-2.5.69-bk16/drivers/net/wan/cycx_x25.c
--- linux-2.5.69-bk15/drivers/net/wan/cycx_x25.c	2003-05-23 04:36:14.000000000 -0700
+++ linux-2.5.69-bk16/drivers/net/wan/cycx_x25.c	2003-05-23 04:36:21.000000000 -0700
@@ -82,7 +82,7 @@
 #include <linux/errno.h>	/* return codes */
 #include <linux/if_arp.h>       /* ARPHRD_HWX25 */
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
-#include <linux/module.h>	/* SET_MODULE_OWNER */
+#include <linux/module.h>
 #include <linux/string.h>	/* inline memset(), etc. */
 #include <linux/slab.h>		/* kmalloc(), kfree() */
 #include <linux/stddef.h>	/* offsetof(), etc. */
diff -urN linux-2.5.69-bk15/drivers/pci/bus.c linux-2.5.69-bk16/drivers/pci/bus.c
--- linux-2.5.69-bk15/drivers/pci/bus.c	2003-05-04 16:53:42.000000000 -0700
+++ linux-2.5.69-bk16/drivers/pci/bus.c	2003-05-23 04:36:21.000000000 -0700
@@ -92,7 +92,7 @@
 		if (!list_empty(&dev->global_list))
 			continue;
 
-		device_register(&dev->dev);
+		device_add(&dev->dev);
 		list_add_tail(&dev->global_list, &pci_devices);
 #ifdef CONFIG_PROC_FS
 		pci_proc_attach_device(dev);
diff -urN linux-2.5.69-bk15/drivers/pci/hotplug.c linux-2.5.69-bk16/drivers/pci/hotplug.c
--- linux-2.5.69-bk15/drivers/pci/hotplug.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk16/drivers/pci/hotplug.c	2003-05-23 04:36:21.000000000 -0700
@@ -207,26 +207,6 @@
 
 #endif /* CONFIG_HOTPLUG */
 
-/**
- * pci_insert_device - insert a pci device
- * @dev: the device to insert
- * @bus: where to insert it
- *
- * Link the device to both the global PCI device chain and the 
- * per-bus list of devices, add the /proc entry.
- */
-void
-pci_insert_device(struct pci_dev *dev, struct pci_bus *bus)
-{
-	list_add_tail(&dev->bus_list, &bus->devices);
-	list_add_tail(&dev->global_list, &pci_devices);
-#ifdef CONFIG_PROC_FS
-	pci_proc_attach_device(dev);
-#endif
-	/* add sysfs device files */
-	pci_create_sysfs_dev_files(dev);
-}
-
 static void
 pci_free_resources(struct pci_dev *dev)
 {
@@ -275,7 +255,7 @@
 	pci_proc_detach_device(dev);
 #endif
 
-	kfree(dev);
+	pci_put_dev(dev);
 }
 
 /**
@@ -300,7 +280,6 @@
 }
 
 #ifdef CONFIG_HOTPLUG
-EXPORT_SYMBOL(pci_insert_device);
 EXPORT_SYMBOL(pci_remove_bus_device);
 EXPORT_SYMBOL(pci_remove_behind_bridge);
 #endif
diff -urN linux-2.5.69-bk15/drivers/pci/pci-driver.c linux-2.5.69-bk16/drivers/pci/pci-driver.c
--- linux-2.5.69-bk15/drivers/pci/pci-driver.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk16/drivers/pci/pci-driver.c	2003-05-23 04:36:21.000000000 -0700
@@ -6,6 +6,8 @@
 #include <linux/pci.h>
 #include <linux/module.h>
 #include <linux/init.h>
+#include <linux/device.h>
+#include <linux/pci-dynids.h>
 #include "pci.h"
 
 /*
@@ -13,7 +15,29 @@
  */
 
 /**
- * pci_match_device - Tell if a PCI device structure has a matching PCI device id structure
+ * pci_match_one_device - Tell if a PCI device structure has a matching
+ *                        PCI device id structure
+ * @id: single PCI device id structure to match
+ * @dev: the PCI device structure to match against
+ * 
+ * Returns the matching pci_device_id structure or %NULL if there is no match.
+ */
+
+static inline const struct pci_device_id *
+pci_match_one_device(const struct pci_device_id *id, const struct pci_dev *dev)
+{
+	if ((id->vendor == PCI_ANY_ID || id->vendor == dev->vendor) &&
+	    (id->device == PCI_ANY_ID || id->device == dev->device) &&
+	    (id->subvendor == PCI_ANY_ID || id->subvendor == dev->subsystem_vendor) &&
+	    (id->subdevice == PCI_ANY_ID || id->subdevice == dev->subsystem_device) &&
+	    !((id->class ^ dev->class) & id->class_mask))
+		return id;
+	return NULL;
+}
+
+/**
+ * pci_match_device - Tell if a PCI device structure has a matching
+ *                    PCI device id structure
  * @ids: array of PCI device id structures to search in
  * @dev: the PCI device structure to match against
  * 
@@ -25,17 +49,87 @@
 pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev)
 {
 	while (ids->vendor || ids->subvendor || ids->class_mask) {
-		if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) &&
-		    (ids->device == PCI_ANY_ID || ids->device == dev->device) &&
-		    (ids->subvendor == PCI_ANY_ID || ids->subvendor == dev->subsystem_vendor) &&
-		    (ids->subdevice == PCI_ANY_ID || ids->subdevice == dev->subsystem_device) &&
-		    !((ids->class ^ dev->class) & ids->class_mask))
+		if (pci_match_one_device(ids, dev))
 			return ids;
 		ids++;
 	}
 	return NULL;
 }
 
+/**
+ * pci_device_probe_static()
+ * 
+ * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
+ */
+static int
+pci_device_probe_static(struct pci_driver *drv, struct pci_dev *pci_dev)
+{		   
+	int error = -ENODEV;
+	const struct pci_device_id *id;
+
+	if (!drv->id_table)
+		return error;
+	id = pci_match_device(drv->id_table, pci_dev);
+	if (id)
+		error = drv->probe(pci_dev, id);
+	if (error >= 0) {
+		pci_dev->driver = drv;
+		return 0;
+	}
+	return error;
+}
+
+/**
+ * pci_device_probe_dynamic()
+ * 
+ * Walk the dynamic ID list looking for a match.
+ * returns 0 and sets pci_dev->driver when drv claims pci_dev, else error.
+ */
+static int
+pci_device_probe_dynamic(struct pci_driver *drv, struct pci_dev *pci_dev)
+{		   
+	int error = -ENODEV;
+	struct list_head *pos;
+	struct dynid *dynid;
+
+	spin_lock(&drv->dynids.lock);
+	list_for_each(pos, &drv->dynids.list) {
+		dynid = list_entry(pos, struct dynid, node);
+		if (pci_match_one_device(&dynid->id, pci_dev)) {
+			spin_unlock(&drv->dynids.lock);
+			error = drv->probe(pci_dev, &dynid->id);
+			if (error >= 0) {
+				pci_dev->driver = drv;
+				return 0;
+			}
+			return error;
+		}
+	}
+	spin_unlock(&drv->dynids.lock);
+	return error;
+}
+
+/**
+ * __pci_device_probe()
+ * 
+ * returns 0  on success, else error.
+ * side-effect: pci_dev->driver is set to drv when drv claims pci_dev.
+ */
+static int
+__pci_device_probe(struct pci_driver *drv, struct pci_dev *pci_dev)
+{		   
+	int error = 0;
+
+	if (!pci_dev->driver && drv->probe) {
+		error = pci_device_probe_static(drv, pci_dev);
+		if (error >= 0)
+			return error;
+
+		error = pci_device_probe_dynamic(drv, pci_dev);
+	}
+	return error;
+}
+
 static int pci_device_probe(struct device * dev)
 {
 	int error = 0;
@@ -44,17 +138,9 @@
 
 	drv = to_pci_driver(dev->driver);
 	pci_dev = to_pci_dev(dev);
-
-	if (!pci_dev->driver && drv->probe) {
-		const struct pci_device_id *id;
-
-		id = pci_match_device(drv->id_table, pci_dev);
-		if (id)
-			error = drv->probe(pci_dev, id);
-		if (error >= 0) {
-			pci_dev->driver = drv;
-			error = 0;
-		}
+	if (get_device(dev)) {
+		error = __pci_device_probe(drv, pci_dev);
+		put_device(dev);
 	}
 	return error;
 }
@@ -101,6 +187,134 @@
 	return 0;
 }
 
+static inline void
+dynid_init(struct dynid *dynid)
+{
+	memset(dynid, 0, sizeof(*dynid));
+	INIT_LIST_HEAD(&dynid->node);
+}
+
+/**
+ * store_new_id
+ * @ pdrv
+ * @ buf
+ * @ count
+ *
+ * Adds a new dynamic pci device ID to this driver,
+ * and causes the driver to probe for all devices again.
+ */
+static inline ssize_t
+store_new_id(struct device_driver * driver, const char * buf, size_t count)
+{
+	struct dynid *dynid;
+	struct bus_type * bus;
+	struct pci_driver *pdrv = to_pci_driver(driver);
+	__u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID,
+		subdevice=PCI_ANY_ID, class=0, class_mask=0;
+	unsigned long driver_data=0;
+	int fields=0;
+
+	fields = sscanf(buf, "%x %x %x %x %x %x %lux",
+			&vendor, &device, &subvendor, &subdevice,
+			&class, &class_mask, &driver_data);
+	if (fields < 0)
+		return -EINVAL;
+
+	dynid = kmalloc(sizeof(*dynid), GFP_KERNEL);
+	if (!dynid)
+		return -ENOMEM;
+	dynid_init(dynid);
+
+	dynid->id.vendor = vendor;
+	dynid->id.device = device;
+	dynid->id.subvendor = subvendor;
+	dynid->id.subdevice = subdevice;
+	dynid->id.class = class;
+	dynid->id.class_mask = class_mask;
+	dynid->id.driver_data = pdrv->dynids.use_driver_data ?
+		driver_data : 0UL;
+
+	spin_lock(&pdrv->dynids.lock);
+	list_add(&pdrv->dynids.list, &dynid->node);
+	spin_unlock(&pdrv->dynids.lock);
+
+	bus = get_bus(pdrv->driver.bus);
+	if (bus) {
+		if (get_driver(&pdrv->driver)) {
+			down_write(&bus->subsys.rwsem);
+			driver_attach(&pdrv->driver);
+			up_write(&bus->subsys.rwsem);
+			put_driver(&pdrv->driver);
+		}
+		put_bus(bus);
+	}
+	
+	return count;
+}
+
+static DRIVER_ATTR(new_id, S_IWUSR, NULL, store_new_id);
+
+#define kobj_to_pci_driver(obj) container_of(obj, struct device_driver, kobj)
+#define attr_to_driver_attribute(obj) container_of(obj, struct driver_attribute, attr)
+
+static ssize_t
+pci_driver_attr_show(struct kobject * kobj, struct attribute *attr, char *buf)
+{
+	struct device_driver *driver = kobj_to_pci_driver(kobj);
+	struct driver_attribute *dattr = attr_to_driver_attribute(attr);
+	ssize_t ret = 0;
+
+	if (get_driver(driver)) {
+		if (dattr->show)
+			ret = dattr->show(driver, buf);
+		put_driver(driver);
+	}
+	return ret;
+}
+
+static ssize_t
+pci_driver_attr_store(struct kobject * kobj, struct attribute *attr,
+		      const char *buf, size_t count)
+{
+	struct device_driver *driver = kobj_to_pci_driver(kobj);
+	struct driver_attribute *dattr = attr_to_driver_attribute(attr);
+	ssize_t ret = 0;
+
+	if (get_driver(driver)) {
+		if (dattr->store)
+			ret = dattr->store(driver, buf, count);
+		put_driver(driver);
+	}
+	return ret;
+}
+
+static struct sysfs_ops pci_driver_sysfs_ops = {
+	.show = pci_driver_attr_show,
+	.store = pci_driver_attr_store,
+};
+static struct kobj_type pci_driver_kobj_type = {
+	.sysfs_ops = &pci_driver_sysfs_ops,
+};
+
+static int
+pci_populate_driver_dir(struct pci_driver * drv)
+{
+	int error = 0;
+
+	if (drv->probe != NULL)
+		error = sysfs_create_file(&drv->driver.kobj,
+					  &driver_attr_new_id.attr);
+	return error;
+}
+
+static inline void
+pci_init_dynids(struct pci_dynids *dynids)
+{
+	memset(dynids, 0, sizeof(*dynids));
+	spin_lock_init(&dynids->lock);
+	INIT_LIST_HEAD(&dynids->list);
+}
+
 /**
  * pci_register_driver - register a new pci driver
  * @drv: the driver structure to register
@@ -122,9 +336,16 @@
 	drv->driver.resume = pci_device_resume;
 	drv->driver.suspend = pci_device_suspend;
 	drv->driver.remove = pci_device_remove;
+	drv->driver.kobj.ktype = &pci_driver_kobj_type;
+	pci_init_dynids(&drv->dynids);
 
 	/* register with core */
 	count = driver_register(&drv->driver);
+
+	if (count >= 0) {
+		pci_populate_driver_dir(drv);
+	}
+
 	return count ? count : 1;
 }
 
@@ -180,25 +401,72 @@
  */
 static int pci_bus_match(struct device * dev, struct device_driver * drv) 
 {
-	struct pci_dev * pci_dev = to_pci_dev(dev);
+	const struct pci_dev * pci_dev = to_pci_dev(dev);
 	struct pci_driver * pci_drv = to_pci_driver(drv);
 	const struct pci_device_id * ids = pci_drv->id_table;
+	const struct pci_device_id *found_id;
+	struct list_head *pos;
+	struct dynid *dynid;
 
-	if (!ids) 
+	if (!ids)
 		return 0;
 
-	while (ids->vendor || ids->subvendor || ids->class_mask) {
-		if ((ids->vendor == PCI_ANY_ID || ids->vendor == pci_dev->vendor) &&
-		    (ids->device == PCI_ANY_ID || ids->device == pci_dev->device) &&
-		    (ids->subvendor == PCI_ANY_ID || ids->subvendor == pci_dev->subsystem_vendor) &&
-		    (ids->subdevice == PCI_ANY_ID || ids->subdevice == pci_dev->subsystem_device) &&
-		    !((ids->class ^ pci_dev->class) & ids->class_mask))
+	found_id = pci_match_device(ids, pci_dev);
+	if (found_id)
+		return 1;
+
+	spin_lock(&pci_drv->dynids.lock);
+	list_for_each(pos, &pci_drv->dynids.list) {
+		dynid = list_entry(pos, struct dynid, node);
+		if (pci_match_one_device(&dynid->id, pci_dev)) {
+			spin_unlock(&pci_drv->dynids.lock);
 			return 1;
-		ids++;
+		}
 	}
+	spin_unlock(&pci_drv->dynids.lock);
+
 	return 0;
 }
 
+/**
+ * pci_get_dev - increments the reference count of the pci device structure
+ * @dev: the device being referenced
+ *
+ * Each live reference to a device should be refcounted.
+ *
+ * Drivers for PCI devices should normally record such references in
+ * their probe() methods, when they bind to a device, and release
+ * them by calling pci_put_dev(), in their disconnect() methods.
+ *
+ * A pointer to the device with the incremented reference counter is returned.
+ */
+struct pci_dev *pci_get_dev (struct pci_dev *dev)
+{
+	struct device *tmp;
+
+	if (!dev)
+		return NULL;
+
+	tmp = get_device(&dev->dev);
+	if (tmp)        
+		return to_pci_dev(tmp);
+	else
+		return NULL;
+}
+
+/**
+ * pci_put_dev - release a use of the pci device structure
+ * @dev: device that's been disconnected
+ *
+ * Must be called when a user of a device is finished with it.  When the last
+ * user of the device calls this function, the memory of the device is freed.
+ */
+void pci_put_dev(struct pci_dev *dev)
+{
+	if (dev)
+		put_device(&dev->dev);
+}
+
 struct bus_type pci_bus_type = {
 	.name		= "pci",
 	.match		= pci_bus_match,
@@ -217,3 +485,5 @@
 EXPORT_SYMBOL(pci_unregister_driver);
 EXPORT_SYMBOL(pci_dev_driver);
 EXPORT_SYMBOL(pci_bus_type);
+EXPORT_SYMBOL(pci_get_dev);
+EXPORT_SYMBOL(pci_put_dev);
diff -urN linux-2.5.69-bk15/drivers/pci/probe.c linux-2.5.69-bk16/drivers/pci/probe.c
--- linux-2.5.69-bk15/drivers/pci/probe.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk16/drivers/pci/probe.c	2003-05-23 04:36:21.000000000 -0700
@@ -462,6 +462,21 @@
 	return 0;
 }
 
+/**
+ * pci_release_dev - free a pci device structure when all users of it are finished.
+ * @dev: device that's been disconnected
+ *
+ * Will be called only by the device core when all users of this pci device are
+ * done.
+ */
+static void pci_release_dev(struct device *dev)
+{
+	struct pci_dev *pci_dev;
+
+	pci_dev = to_pci_dev(dev);
+	kfree(pci_dev);
+}
+
 /*
  * Read the config data for a PCI device, sanity-check it
  * and fill in the dev structure...
@@ -506,6 +521,9 @@
 		kfree(dev);
 		return NULL;
 	}
+	device_initialize(&dev->dev);
+	dev->dev.release = pci_release_dev;
+	pci_get_dev(dev);
 
 	pci_name_device(dev);
 
diff -urN linux-2.5.69-bk15/drivers/scsi/aic7xxx/aic7xxx_osm.c linux-2.5.69-bk16/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- linux-2.5.69-bk15/drivers/scsi/aic7xxx/aic7xxx_osm.c	2003-05-23 04:36:15.000000000 -0700
+++ linux-2.5.69-bk16/drivers/scsi/aic7xxx/aic7xxx_osm.c	2003-05-23 04:36:21.000000000 -0700
@@ -1837,7 +1837,7 @@
 }
 
 uint64_t
-ahc_linux_get_memsize()
+ahc_linux_get_memsize(void)
 {
 	struct sysinfo si;
 
@@ -1852,7 +1852,7 @@
  * scenario.
  */
 static int
-ahc_linux_next_unit()
+ahc_linux_next_unit(void)
 {
 	struct ahc_softc *ahc;
 	int unit;
diff -urN linux-2.5.69-bk15/drivers/scsi/sg.c linux-2.5.69-bk16/drivers/scsi/sg.c
--- linux-2.5.69-bk15/drivers/scsi/sg.c	2003-05-23 04:36:15.000000000 -0700
+++ linux-2.5.69-bk16/drivers/scsi/sg.c	2003-05-23 04:36:22.000000000 -0700
@@ -2658,7 +2658,7 @@
 
 #ifdef CONFIG_PROC_FS
 static int
-sg_last_dev()
+sg_last_dev(void)
 {
 	int k;
 	unsigned long iflags;
@@ -2770,7 +2770,7 @@
 extern struct proc_dir_entry *proc_scsi;
 
 static int
-sg_proc_init()
+sg_proc_init(void)
 {
 	int k, mask;
 	int num_leaves =
@@ -2798,7 +2798,7 @@
 }
 
 static void
-sg_proc_cleanup()
+sg_proc_cleanup(void)
 {
 	int k;
 	int num_leaves =
diff -urN linux-2.5.69-bk15/include/asm-alpha/agp_backend.h linux-2.5.69-bk16/include/asm-alpha/agp_backend.h
--- linux-2.5.69-bk15/include/asm-alpha/agp_backend.h	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk16/include/asm-alpha/agp_backend.h	2003-05-23 04:36:23.000000000 -0700
@@ -17,7 +17,6 @@
 } alpha_agp_mode;
 
 typedef struct _alpha_agp_info {
-	enum chipset_type type;
 	struct pci_controller *hose;
 	struct {
 		dma_addr_t bus_base;
diff -urN linux-2.5.69-bk15/include/linux/agp_backend.h linux-2.5.69-bk16/include/linux/agp_backend.h
--- linux-2.5.69-bk15/include/linux/agp_backend.h	2003-05-23 04:36:16.000000000 -0700
+++ linux-2.5.69-bk16/include/linux/agp_backend.h	2003-05-23 04:36:23.000000000 -0700
@@ -1,5 +1,6 @@
 /*
- * AGPGART module version 0.100
+ * AGPGART backend specific includes. Not for userspace consumption.
+ *
  * Copyright (C) 2002-2003 Dave Jones
  * Copyright (C) 1999 Jeff Hartmann
  * Copyright (C) 1999 Precision Insight, Inc.
@@ -28,6 +29,8 @@
 #ifndef _AGP_BACKEND_H
 #define _AGP_BACKEND_H 1
 
+#ifdef __KERNEL__
+
 #ifndef TRUE
 #define TRUE 1
 #endif
@@ -46,7 +49,7 @@
 	u16 minor;
 };
 
-typedef struct _agp_kern_info {
+struct agp_kern_info {
 	struct agp_version version;
 	struct pci_dev *device;
 	enum chipset_type chipset;
@@ -58,7 +61,7 @@
 	int cant_use_aperture;
 	unsigned long page_mask;
 	struct vm_operations_struct *vm_ops;
-} agp_kern_info;
+};
 
 /* 
  * The agp_memory structure has information about the block of agp memory
@@ -68,10 +71,10 @@
  * the items to detrimine the status of this block of agp memory. 
  */
 
-typedef struct _agp_memory {
+struct agp_memory {
 	int key;
-	struct _agp_memory *next;
-	struct _agp_memory *prev;
+	struct agp_memory *next;
+	struct agp_memory *prev;
 	size_t page_count;
 	int num_scratch_pages;
 	unsigned long *memory;
@@ -80,15 +83,15 @@
 	u32 physical;
 	u8 is_bound;
 	u8 is_flushed;
-} agp_memory;
+};
 
 #define AGP_NORMAL_MEMORY 0
 
-extern void agp_free_memory(agp_memory *);
-extern agp_memory *agp_allocate_memory(size_t, u32);
-extern int agp_copy_info(agp_kern_info *);
-extern int agp_bind_memory(agp_memory *, off_t);
-extern int agp_unbind_memory(agp_memory *);
+extern void agp_free_memory(struct agp_memory *);
+extern struct agp_memory *agp_allocate_memory(size_t, u32);
+extern int agp_copy_info(struct agp_kern_info *);
+extern int agp_bind_memory(struct agp_memory *, off_t);
+extern int agp_unbind_memory(struct agp_memory *);
 extern void agp_enable(u32);
 extern int agp_backend_acquire(void);
 extern void agp_backend_release(void);
@@ -99,16 +102,17 @@
  * use it.  Keith Owens <kaos@ocs.com.au> 28 Oct 2000.
  */
 typedef struct {
-	void       (*free_memory)(agp_memory *);
-	agp_memory *(*allocate_memory)(size_t, u32);
-	int        (*bind_memory)(agp_memory *, off_t);
-	int        (*unbind_memory)(agp_memory *);
-	void       (*enable)(u32);
-	int        (*acquire)(void);
-	void       (*release)(void);
-	int        (*copy_info)(agp_kern_info *);
+	void			(*free_memory)(struct agp_memory *);
+	struct agp_memory *	(*allocate_memory)(size_t, u32);
+	int			(*bind_memory)(struct agp_memory *, off_t);
+	int			(*unbind_memory)(struct agp_memory *);
+	void			(*enable)(u32);
+	int			(*acquire)(void);
+	void			(*release)(void);
+	int			(*copy_info)(struct agp_kern_info *);
 } drm_agp_t;
 
 extern const drm_agp_t *drm_agp_p;
 
+#endif				/* __KERNEL__ */
 #endif				/* _AGP_BACKEND_H */
diff -urN linux-2.5.69-bk15/include/linux/agpgart.h linux-2.5.69-bk16/include/linux/agpgart.h
--- linux-2.5.69-bk15/include/linux/agpgart.h	2003-05-23 04:36:16.000000000 -0700
+++ linux-2.5.69-bk16/include/linux/agpgart.h	2003-05-23 04:36:23.000000000 -0700
@@ -183,7 +183,7 @@
 	struct agp_controller *prev;
 	pid_t pid;
 	int num_clients;
-	agp_memory *pool;
+	struct agp_memory *pool;
 	struct agp_client *clients;
 };
 
diff -urN linux-2.5.69-bk15/include/linux/arcdevice.h linux-2.5.69-bk16/include/linux/arcdevice.h
--- linux-2.5.69-bk15/include/linux/arcdevice.h	2003-05-04 16:53:07.000000000 -0700
+++ linux-2.5.69-bk16/include/linux/arcdevice.h	2003-05-23 04:36:23.000000000 -0700
@@ -333,14 +333,5 @@
 void arcdev_setup(struct net_device *dev);
 void arcnet_rx(struct net_device *dev, int bufnum);
 
-void arcnet_init(void);
-
-void arcnet_rfc1201_init(void);
-void arcnet_rfc1051_init(void);
-void arcnet_raw_init(void);
-
-int com90xx_probe(struct net_device *dev);
-
 #endif				/* __KERNEL__ */
-
 #endif				/* _LINUX_ARCDEVICE_H */
diff -urN linux-2.5.69-bk15/include/linux/device.h linux-2.5.69-bk16/include/linux/device.h
--- linux-2.5.69-bk15/include/linux/device.h	2003-05-23 04:36:16.000000000 -0700
+++ linux-2.5.69-bk16/include/linux/device.h	2003-05-23 04:36:23.000000000 -0700
@@ -319,6 +319,7 @@
  */
 extern void device_bind_driver(struct device * dev);
 extern void device_release_driver(struct device * dev);
+extern void driver_attach(struct device_driver * drv);
 
 
 /* driverfs interface for exporting device attributes */
diff -urN linux-2.5.69-bk15/include/linux/netfilter_ipv4/ip_tables.h linux-2.5.69-bk16/include/linux/netfilter_ipv4/ip_tables.h
--- linux-2.5.69-bk15/include/linux/netfilter_ipv4/ip_tables.h	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk16/include/linux/netfilter_ipv4/ip_tables.h	2003-05-23 04:36:23.000000000 -0700
@@ -347,13 +347,14 @@
 
 	/* Return true or false: return FALSE and set *hotdrop = 1 to
            force immediate packet drop. */
+	/* Arguments changed since 2.4, as this must now handle
+           non-linear skbs, using skb_copy_bits and
+           skb_ip_make_writable. */
 	int (*match)(const struct sk_buff *skb,
 		     const struct net_device *in,
 		     const struct net_device *out,
 		     const void *matchinfo,
 		     int offset,
-		     const void *hdr,
-		     u_int16_t datalen,
 		     int *hotdrop);
 
 	/* Called when user tries to insert an entry of this type. */
@@ -367,7 +368,7 @@
 	/* Called when entry of this type deleted. */
 	void (*destroy)(void *matchinfo, unsigned int matchinfosize);
 
-	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
+	/* Set this to THIS_MODULE. */
 	struct module *me;
 };
 
@@ -378,14 +379,6 @@
 
 	const char name[IPT_FUNCTION_MAXNAMELEN];
 
-	/* Returns verdict. */
-	unsigned int (*target)(struct sk_buff **pskb,
-			       unsigned int hooknum,
-			       const struct net_device *in,
-			       const struct net_device *out,
-			       const void *targinfo,
-			       void *userdata);
-
 	/* Called when user tries to insert an entry of this type:
            hook_mask is a bitmask of hooks from which it can be
            called. */
@@ -399,7 +392,17 @@
 	/* Called when entry of this type deleted. */
 	void (*destroy)(void *targinfo, unsigned int targinfosize);
 
-	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
+	/* Returns verdict.  Argument order changed since 2.4, as this
+           must now handle non-linear skbs, using skb_copy_bits and
+           skb_ip_make_writable. */
+	unsigned int (*target)(struct sk_buff **pskb,
+			       const struct net_device *in,
+			       const struct net_device *out,
+			       unsigned int hooknum,
+			       const void *targinfo,
+			       void *userdata);
+
+	/* Set this to THIS_MODULE. */
 	struct module *me;
 };
 
@@ -429,7 +432,7 @@
 	/* Man behind the curtain... */
 	struct ipt_table_info *private;
 
-	/* Set this to THIS_MODULE if you are a module, otherwise NULL */
+	/* Set to THIS_MODULE. */
 	struct module *me;
 };
 
diff -urN linux-2.5.69-bk15/include/linux/pci-dynids.h linux-2.5.69-bk16/include/linux/pci-dynids.h
--- linux-2.5.69-bk15/include/linux/pci-dynids.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.5.69-bk16/include/linux/pci-dynids.h	2003-05-23 04:36:23.000000000 -0700
@@ -0,0 +1,18 @@
+/*
+ *	PCI defines and function prototypes
+ *	Copyright 2003 Dell Computer Corporation
+ *        by Matt Domsch <Matt_Domsch@dell.com>
+ */
+
+#ifndef LINUX_PCI_DYNIDS_H
+#define LINUX_PCI_DYNIDS_H
+
+#include <linux/list.h>
+#include <linux/mod_devicetable.h>
+
+struct dynid {
+	struct list_head        node;
+	struct pci_device_id    id;
+};
+
+#endif
diff -urN linux-2.5.69-bk15/include/linux/pci.h linux-2.5.69-bk16/include/linux/pci.h
--- linux-2.5.69-bk15/include/linux/pci.h	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk16/include/linux/pci.h	2003-05-23 04:36:23.000000000 -0700
@@ -490,10 +490,16 @@
 	unsigned long end;
 };
 
+struct pci_dynids {
+	spinlock_t lock;            /* protects list, index */
+	struct list_head list;      /* for IDs added at runtime */
+	unsigned int use_driver_data:1; /* pci_driver->driver_data is used */
+};
+
 struct pci_driver {
 	struct list_head node;
 	char *name;
-	const struct pci_device_id *id_table;	/* NULL if wants all devices */
+	const struct pci_device_id *id_table;	/* must be non-NULL for probe to be called */
 	int  (*probe)  (struct pci_dev *dev, const struct pci_device_id *id);	/* New device inserted */
 	void (*remove) (struct pci_dev *dev);	/* Device removed (NULL if not a hot-plug capable driver) */
 	int  (*save_state) (struct pci_dev *dev, u32 state);    /* Save Device Context */
@@ -502,6 +508,7 @@
 	int  (*enable_wake) (struct pci_dev *dev, u32 state, int enable);   /* Enable wake event */
 
 	struct device_driver	driver;
+	struct pci_dynids dynids;
 };
 
 #define	to_pci_driver(drv) container_of(drv,struct pci_driver, driver)
@@ -556,6 +563,8 @@
 struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res);
 int pci_setup_device(struct pci_dev *dev);
 int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge);
+extern struct pci_dev *pci_get_dev(struct pci_dev *dev);
+extern void pci_put_dev(struct pci_dev *dev);
 
 /* Generic PCI functions exported to card drivers */
 
@@ -651,7 +660,6 @@
 /* New-style probing supporting hot-pluggable devices */
 int pci_register_driver(struct pci_driver *);
 void pci_unregister_driver(struct pci_driver *);
-void pci_insert_device(struct pci_dev *, struct pci_bus *);
 void pci_remove_bus_device(struct pci_dev *);
 void pci_remove_behind_bridge(struct pci_dev *);
 struct pci_driver *pci_dev_driver(const struct pci_dev *);
@@ -702,6 +710,12 @@
 			 struct pci_bus_wrapped *wrapped_parent);
 extern int pci_remove_device_safe(struct pci_dev *dev);
 
+static inline void
+pci_dynids_set_use_driver_data(struct pci_driver *pdrv, int val)
+{
+	pdrv->dynids.use_driver_data = val;
+}
+
 #endif /* CONFIG_PCI */
 
 /* Include architecture-dependent settings and functions */
@@ -750,6 +764,7 @@
 static inline int scsi_to_pci_dma_dir(unsigned char scsi_dir) { return scsi_dir; }
 static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; }
 static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; }
+static inline void pci_dynids_set_use_driver_data(struct pci_driver *pdrv, int val) { }
 
 /* Power management related routines */
 static inline int pci_save_state(struct pci_dev *dev, u32 *buffer) { return 0; }
diff -urN linux-2.5.69-bk15/include/net/flow.h linux-2.5.69-bk16/include/net/flow.h
--- linux-2.5.69-bk15/include/net/flow.h	2003-05-23 04:36:16.000000000 -0700
+++ linux-2.5.69-bk16/include/net/flow.h	2003-05-23 04:36:23.000000000 -0700
@@ -7,6 +7,8 @@
 #ifndef _NET_FLOW_H
 #define _NET_FLOW_H
 
+#include <linux/in6.h>
+
 struct flowi {
 	int	oif;
 	int	iif;
@@ -21,8 +23,8 @@
 		} ip4_u;
 		
 		struct {
-			struct in6_addr *	daddr;
-			struct in6_addr *	saddr;
+			struct in6_addr		daddr;
+			struct in6_addr		saddr;
 			__u32			flowlabel;
 		} ip6_u;
 
diff -urN linux-2.5.69-bk15/include/net/ip.h linux-2.5.69-bk16/include/net/ip.h
--- linux-2.5.69-bk15/include/net/ip.h	2003-05-23 04:36:16.000000000 -0700
+++ linux-2.5.69-bk16/include/net/ip.h	2003-05-23 04:36:23.000000000 -0700
@@ -295,7 +295,6 @@
 extern void	ip_local_error(struct sock *sk, int err, u32 daddr, u16 dport,
 			       u32 info);
 
-extern int ip_seq_release(struct inode *inode, struct file *file);
 extern int ipv4_proc_init(void);
 
 /* sysctl helpers - any sysctl which holds a value that ends up being
diff -urN linux-2.5.69-bk15/include/net/ipv6.h linux-2.5.69-bk16/include/net/ipv6.h
--- linux-2.5.69-bk15/include/net/ipv6.h	2003-05-23 04:36:16.000000000 -0700
+++ linux-2.5.69-bk16/include/net/ipv6.h	2003-05-23 04:36:23.000000000 -0700
@@ -334,8 +334,7 @@
 
 extern int			ip6_dst_lookup(struct sock *sk,
 					       struct dst_entry **dst,
-					       struct flowi *fl,
-					       struct in6_addr **saddr);
+					       struct flowi *fl);
 
 /*
  *	skb processing functions
diff -urN linux-2.5.69-bk15/include/net/transp_v6.h linux-2.5.69-bk16/include/net/transp_v6.h
--- linux-2.5.69-bk15/include/net/transp_v6.h	2003-05-04 16:53:57.000000000 -0700
+++ linux-2.5.69-bk16/include/net/transp_v6.h	2003-05-23 04:36:23.000000000 -0700
@@ -16,7 +16,6 @@
 struct flowi;
 
 /* extention headers */
-extern void				ipv6_hopopts_init(void);
 extern void				ipv6_rthdr_init(void);
 extern void				ipv6_frag_init(void);
 extern void				ipv6_nodata_init(void);
diff -urN linux-2.5.69-bk15/include/net/xfrm.h linux-2.5.69-bk16/include/net/xfrm.h
--- linux-2.5.69-bk15/include/net/xfrm.h	2003-05-23 04:36:16.000000000 -0700
+++ linux-2.5.69-bk16/include/net/xfrm.h	2003-05-23 04:36:23.000000000 -0700
@@ -315,14 +315,14 @@
 
 static inline u32 __flow_hash6(struct flowi *fl)
 {
-	u32 hash = fl->fl6_src->s6_addr32[2] ^
-		   fl->fl6_src->s6_addr32[3] ^ 
+	u32 hash = fl->fl6_src.s6_addr32[2] ^
+		   fl->fl6_src.s6_addr32[3] ^ 
 		   fl->fl_ip_sport;
 
 	hash = ((hash & 0xF0F0F0F0) >> 4) | ((hash & 0x0F0F0F0F) << 4);
 
-	hash ^= fl->fl6_dst->s6_addr32[2] ^
-		fl->fl6_dst->s6_addr32[3] ^ 
+	hash ^= fl->fl6_dst.s6_addr32[2] ^
+		fl->fl6_dst.s6_addr32[3] ^ 
 		fl->fl_ip_dport;
 	hash ^= (hash >> 10);
 	hash ^= (hash >> 20);
@@ -471,8 +471,8 @@
 static inline int
 __xfrm6_selector_match(struct xfrm_selector *sel, struct flowi *fl)
 {
-	return  addr_match(fl->fl6_dst, &sel->daddr, sel->prefixlen_d) &&
-		addr_match(fl->fl6_src, &sel->saddr, sel->prefixlen_s) &&
+	return  addr_match(&fl->fl6_dst, &sel->daddr, sel->prefixlen_d) &&
+		addr_match(&fl->fl6_src, &sel->saddr, sel->prefixlen_s) &&
 		!((fl->fl_ip_dport^sel->dport)&sel->dport_mask) &&
 		!((fl->fl_ip_sport^sel->sport)&sel->sport_mask) &&
 		(fl->proto == sel->proto || !sel->proto) &&
@@ -654,7 +654,7 @@
 	case AF_INET:
 		return (xfrm_address_t *)&fl->fl4_dst;
 	case AF_INET6:
-		return (xfrm_address_t *)fl->fl6_dst;
+		return (xfrm_address_t *)&fl->fl6_dst;
 	}
 	return NULL;
 }
@@ -666,7 +666,7 @@
 	case AF_INET:
 		return (xfrm_address_t *)&fl->fl4_src;
 	case AF_INET6:
-		return (xfrm_address_t *)fl->fl6_src;
+		return (xfrm_address_t *)&fl->fl6_src;
 	}
 	return NULL;
 }
diff -urN linux-2.5.69-bk15/mm/vmscan.c linux-2.5.69-bk16/mm/vmscan.c
--- linux-2.5.69-bk15/mm/vmscan.c	2003-05-23 04:36:16.000000000 -0700
+++ linux-2.5.69-bk16/mm/vmscan.c	2003-05-23 04:36:23.000000000 -0700
@@ -1010,7 +1010,11 @@
 	pg_data_t *pgdat;
 	int nr_to_free = nr_pages;
 	int ret = 0;
+	struct reclaim_state reclaim_state = {
+		.reclaimed_slab = 0,
+	};
 
+	current->reclaim_state = &reclaim_state;
 	for_each_pgdat(pgdat) {
 		int freed;
 		struct page_state ps;
@@ -1022,6 +1026,7 @@
 		if (nr_to_free <= 0)
 			break;
 	}
+	current->reclaim_state = NULL;
 	return ret;
 }
 #endif
diff -urN linux-2.5.69-bk15/net/core/dev.c linux-2.5.69-bk16/net/core/dev.c
--- linux-2.5.69-bk15/net/core/dev.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/core/dev.c	2003-05-23 04:36:23.000000000 -0700
@@ -2863,9 +2863,6 @@
 
 extern void net_device_init(void);
 extern void ip_auto_config(void);
-#ifdef CONFIG_NET_DIVERT
-extern void dv_init(void);
-#endif /* CONFIG_NET_DIVERT */
 
 
 /*
@@ -2889,10 +2886,6 @@
 	for (i = 0; i < 16; i++) 
 		INIT_LIST_HEAD(&ptype_base[i]);
 
-#ifdef CONFIG_NET_DIVERT
-	dv_init();
-#endif /* CONFIG_NET_DIVERT */
-
 	/*
 	 *	Initialise the packet receive queues.
 	 */
diff -urN linux-2.5.69-bk15/net/core/dst.c linux-2.5.69-bk16/net/core/dst.c
--- linux-2.5.69-bk15/net/core/dst.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/core/dst.c	2003-05-23 04:36:23.000000000 -0700
@@ -123,6 +123,7 @@
 	if (!dst)
 		return NULL;
 	memset(dst, 0, ops->entry_size);
+	atomic_set(&dst->__refcnt, 0);
 	dst->ops = ops;
 	dst->lastuse = jiffies;
 	dst->path = dst;
diff -urN linux-2.5.69-bk15/net/core/dv.c linux-2.5.69-bk16/net/core/dv.c
--- linux-2.5.69-bk15/net/core/dv.c	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk16/net/core/dv.c	2003-05-23 04:36:23.000000000 -0700
@@ -40,11 +40,12 @@
 
 const char sysctl_divert_version[32]="0.46";	/* Current version */
 
-int __init dv_init(void)
+static int __init dv_init(void)
 {
 	printk(KERN_INFO "NET4: Frame Diverter %s\n", sysctl_divert_version);
 	return 0;
 }
+module_init(dv_init);
 
 /*
  * Allocate a divert_blk for a device. This must be an ethernet nic.
diff -urN linux-2.5.69-bk15/net/core/rtnetlink.c linux-2.5.69-bk16/net/core/rtnetlink.c
--- linux-2.5.69-bk15/net/core/rtnetlink.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/core/rtnetlink.c	2003-05-23 04:36:23.000000000 -0700
@@ -52,7 +52,7 @@
 
 DECLARE_MUTEX(rtnl_sem);
 
-void rtnl_lock()
+void rtnl_lock(void)
 {
 	rtnl_shlock();
 	rtnl_exlock();
diff -urN linux-2.5.69-bk15/net/ipv4/Kconfig linux-2.5.69-bk16/net/ipv4/Kconfig
--- linux-2.5.69-bk15/net/ipv4/Kconfig	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/Kconfig	2003-05-23 04:36:23.000000000 -0700
@@ -125,13 +125,6 @@
 	  handled by the klogd daemon which is responsible for kernel messages
 	  ("man klogd").
 
-config IP_ROUTE_LARGE_TABLES
-	bool "IP: large routing tables"
-	depends on IP_ADVANCED_ROUTER
-	help
-	  If you have routing zones that grow to more than about 64 entries,
-	  you may want to say Y here to speed up the routing process.
-
 config IP_PNP
 	bool "IP: kernel level autoconfiguration"
 	depends on INET
diff -urN linux-2.5.69-bk15/net/ipv4/arp.c linux-2.5.69-bk16/net/ipv4/arp.c
--- linux-2.5.69-bk15/net/ipv4/arp.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/arp.c	2003-05-23 04:36:23.000000000 -0700
@@ -1389,7 +1389,7 @@
 	.open           = arp_seq_open,
 	.read           = seq_read,
 	.llseek         = seq_lseek,
-	.release	= ip_seq_release,
+	.release	= seq_release_private,
 };
 
 static int __init arp_proc_init(void)
diff -urN linux-2.5.69-bk15/net/ipv4/esp.c linux-2.5.69-bk16/net/ipv4/esp.c
--- linux-2.5.69-bk15/net/ipv4/esp.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/esp.c	2003-05-23 04:36:23.000000000 -0700
@@ -578,7 +578,7 @@
 		decap_data_too_small();
 	}
 
-	SET_MODULE_OWNER(&esp_type);
+	esp_type.owner = THIS_MODULE;
 	if (xfrm_register_type(&esp_type, AF_INET) < 0) {
 		printk(KERN_INFO "ip esp init: can't add xfrm type\n");
 		return -EAGAIN;
diff -urN linux-2.5.69-bk15/net/ipv4/fib_hash.c linux-2.5.69-bk16/net/ipv4/fib_hash.c
--- linux-2.5.69-bk15/net/ipv4/fib_hash.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/fib_hash.c	2003-05-23 04:36:23.000000000 -0700
@@ -89,7 +89,7 @@
 	int		fz_nent;	/* Number of entries	*/
 
 	int		fz_divisor;	/* Hash divisor		*/
-	u32		fz_hashmask;	/* (1<<fz_divisor) - 1	*/
+	u32		fz_hashmask;	/* (fz_divisor - 1)	*/
 #define FZ_HASHMASK(fz)	((fz)->fz_hashmask)
 
 	int		fz_order;	/* Zone order		*/
@@ -149,9 +149,30 @@
 
 static rwlock_t fib_hash_lock = RW_LOCK_UNLOCKED;
 
-#define FZ_MAX_DIVISOR 1024
+#define FZ_MAX_DIVISOR ((PAGE_SIZE<<MAX_ORDER) / sizeof(struct fib_node *))
 
-#ifdef CONFIG_IP_ROUTE_LARGE_TABLES
+static unsigned long size_to_order(unsigned long size)
+{
+	unsigned long order;
+
+	for (order = 0; order < MAX_ORDER; order++) {
+		if ((PAGE_SIZE << order) >= size)
+			break;
+	}
+	return order;
+}
+
+static struct fib_node **fz_hash_alloc(int divisor)
+{
+	unsigned long size = divisor * sizeof(struct fib_node *);
+
+	if (divisor <= 1024) {
+		return kmalloc(size, GFP_KERNEL);
+	} else {
+		return (struct fib_node **)
+			__get_free_pages(GFP_KERNEL, size_to_order(size));
+	}
+}
 
 /* The fib hash lock must be held when this is called. */
 static __inline__ void fn_rebuild_zone(struct fn_zone *fz,
@@ -174,6 +195,15 @@
 	}
 }
 
+static void fz_hash_free(struct fib_node **hash, int divisor)
+{
+	if (divisor <= 1024)
+		kfree(hash);
+	else
+		free_pages((unsigned long) hash,
+			   size_to_order(divisor * sizeof(struct fib_node *)));
+}
+
 static void fn_rehash_zone(struct fn_zone *fz)
 {
 	struct fib_node **ht, **old_ht;
@@ -185,24 +215,30 @@
 	switch (old_divisor) {
 	case 16:
 		new_divisor = 256;
-		new_hashmask = 0xFF;
 		break;
 	case 256:
 		new_divisor = 1024;
-		new_hashmask = 0x3FF;
 		break;
 	default:
-		printk(KERN_CRIT "route.c: bad divisor %d!\n", old_divisor);
-		return;
+		if ((old_divisor << 1) > FZ_MAX_DIVISOR) {
+			printk(KERN_CRIT "route.c: bad divisor %d!\n", old_divisor);
+			return;
+		}
+		new_divisor = (old_divisor << 1);
+		break;
 	}
+
+	new_hashmask = (new_divisor - 1);
+
 #if RT_CACHE_DEBUG >= 2
 	printk("fn_rehash_zone: hash for zone %d grows from %d\n", fz->fz_order, old_divisor);
 #endif
 
-	ht = kmalloc(new_divisor*sizeof(struct fib_node*), GFP_KERNEL);
+	ht = fz_hash_alloc(new_divisor);
 
 	if (ht)	{
 		memset(ht, 0, new_divisor*sizeof(struct fib_node*));
+
 		write_lock_bh(&fib_hash_lock);
 		old_ht = fz->fz_hash;
 		fz->fz_hash = ht;
@@ -210,10 +246,10 @@
 		fz->fz_divisor = new_divisor;
 		fn_rebuild_zone(fz, old_ht, old_divisor);
 		write_unlock_bh(&fib_hash_lock);
-		kfree(old_ht);
+
+		fz_hash_free(old_ht, old_divisor);
 	}
 }
-#endif /* CONFIG_IP_ROUTE_LARGE_TABLES */
 
 static void fn_free_node(struct fib_node * f)
 {
@@ -233,12 +269,11 @@
 	memset(fz, 0, sizeof(struct fn_zone));
 	if (z) {
 		fz->fz_divisor = 16;
-		fz->fz_hashmask = 0xF;
 	} else {
 		fz->fz_divisor = 1;
-		fz->fz_hashmask = 0;
 	}
-	fz->fz_hash = kmalloc(fz->fz_divisor*sizeof(struct fib_node*), GFP_KERNEL);
+	fz->fz_hashmask = (fz->fz_divisor - 1);
+	fz->fz_hash = fz_hash_alloc(fz->fz_divisor);
 	if (!fz->fz_hash) {
 		kfree(fz);
 		return NULL;
@@ -467,12 +502,10 @@
 	if  ((fi = fib_create_info(r, rta, n, &err)) == NULL)
 		return err;
 
-#ifdef CONFIG_IP_ROUTE_LARGE_TABLES
-	if (fz->fz_nent > (fz->fz_divisor<<2) &&
+	if (fz->fz_nent > (fz->fz_divisor<<1) &&
 	    fz->fz_divisor < FZ_MAX_DIVISOR &&
 	    (z==32 || (1<<z) > fz->fz_divisor))
 		fn_rehash_zone(fz);
-#endif
 
 	fp = fz_chain_p(key, fz);
 
@@ -1069,7 +1102,7 @@
 	.open           = fib_seq_open,
 	.read           = seq_read,
 	.llseek         = seq_lseek,
-	.release	= ip_seq_release,
+	.release	= seq_release_private,
 };
 
 int __init fib_proc_init(void)
diff -urN linux-2.5.69-bk15/net/ipv4/ipcomp.c linux-2.5.69-bk16/net/ipv4/ipcomp.c
--- linux-2.5.69-bk15/net/ipv4/ipcomp.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/ipcomp.c	2003-05-23 04:36:23.000000000 -0700
@@ -400,7 +400,7 @@
 
 static int __init ipcomp4_init(void)
 {
-	SET_MODULE_OWNER(&ipcomp_type);
+	ipcomp_type.owner = THIS_MODULE;
 	if (xfrm_register_type(&ipcomp_type, AF_INET) < 0) {
 		printk(KERN_INFO "ipcomp init: can't add xfrm type\n");
 		return -EAGAIN;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ip_nat_rule.c linux-2.5.69-bk16/net/ipv4/netfilter/ip_nat_rule.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ip_nat_rule.c	2003-05-04 16:53:13.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ip_nat_rule.c	2003-05-23 04:36:23.000000000 -0700
@@ -111,9 +111,9 @@
 
 /* Source NAT */
 static unsigned int ipt_snat_target(struct sk_buff **pskb,
-				    unsigned int hooknum,
 				    const struct net_device *in,
 				    const struct net_device *out,
+				    unsigned int hooknum,
 				    const void *targinfo,
 				    void *userinfo)
 {
@@ -132,9 +132,9 @@
 }
 
 static unsigned int ipt_dnat_target(struct sk_buff **pskb,
-				    unsigned int hooknum,
 				    const struct net_device *in,
 				    const struct net_device *out,
+				    unsigned int hooknum,
 				    const void *targinfo,
 				    void *userinfo)
 {
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ip_tables.c linux-2.5.69-bk16/net/ipv4/netfilter/ip_tables.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ip_tables.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ip_tables.c	2003-05-23 04:36:23.000000000 -0700
@@ -214,9 +214,9 @@
 
 static unsigned int
 ipt_error(struct sk_buff **pskb,
-	  unsigned int hooknum,
 	  const struct net_device *in,
 	  const struct net_device *out,
+	  unsigned int hooknum,
 	  const void *targinfo,
 	  void *userinfo)
 {
@@ -232,13 +232,10 @@
 	     const struct net_device *in,
 	     const struct net_device *out,
 	     int offset,
-	     const void *hdr,
-	     u_int16_t datalen,
 	     int *hotdrop)
 {
 	/* Stop iteration if it doesn't match */
-	if (!m->u.kernel.match->match(skb, in, out, m->data,
-				      offset, hdr, datalen, hotdrop))
+	if (!m->u.kernel.match->match(skb, in, out, m->data, offset, hotdrop))
 		return 1;
 	else
 		return 0;
@@ -262,7 +259,6 @@
 	static const char nulldevname[IFNAMSIZ] = { 0 };
 	u_int16_t offset;
 	struct iphdr *ip;
-	void *protohdr;
 	u_int16_t datalen;
 	int hotdrop = 0;
 	/* Initializing verdict to NF_DROP keeps gcc happy. */
@@ -271,13 +267,8 @@
 	void *table_base;
 	struct ipt_entry *e, *back;
 
-	/* FIXME: Push down to extensions --RR */
-	if (skb_is_nonlinear(*pskb) && skb_linearize(*pskb, GFP_ATOMIC) != 0)
-		return NF_DROP;
-
 	/* Initialization */
 	ip = (*pskb)->nh.iph;
-	protohdr = (u_int32_t *)ip + ip->ihl;
 	datalen = (*pskb)->len - ip->ihl * 4;
 	indev = in ? in->name : nulldevname;
 	outdev = out ? out->name : nulldevname;
@@ -320,8 +311,7 @@
 
 			if (IPT_MATCH_ITERATE(e, do_match,
 					      *pskb, in, out,
-					      offset, protohdr,
-					      datalen, &hotdrop) != 0)
+					      offset, &hotdrop) != 0)
 				goto no_match;
 
 			ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1);
@@ -364,8 +354,8 @@
 					= 0xeeeeeeec;
 #endif
 				verdict = t->u.kernel.target->target(pskb,
-								     hook,
 								     in, out,
+								     hook,
 								     t->data,
 								     userdata);
 
@@ -382,7 +372,6 @@
 #endif
 				/* Target might have changed stuff. */
 				ip = (*pskb)->nh.iph;
-				protohdr = (u_int32_t *)ip + ip->ihl;
 				datalen = (*pskb)->len - ip->ihl * 4;
 
 				if (verdict == IPT_CONTINUE)
@@ -1458,22 +1447,24 @@
 
 static int
 tcp_find_option(u_int8_t option,
-		const struct tcphdr *tcp,
-		u_int16_t datalen,
+		const struct sk_buff *skb,
+		unsigned int optlen,
 		int invert,
 		int *hotdrop)
 {
-	unsigned int i = sizeof(struct tcphdr);
-	const u_int8_t *opt = (u_int8_t *)tcp;
+	/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
+	char opt[60 - sizeof(struct tcphdr)];
+	unsigned int i;
 
 	duprintf("tcp_match: finding option\n");
 	/* If we don't have the whole header, drop packet. */
-	if (tcp->doff * 4 > datalen) {
+	if (skb_copy_bits(skb, skb->nh.iph->ihl*4 + sizeof(struct tcphdr),
+			  opt, optlen) < 0) {
 		*hotdrop = 1;
 		return 0;
 	}
 
-	while (i < tcp->doff * 4) {
+	for (i = 0; i < optlen; ) {
 		if (opt[i] == option) return !invert;
 		if (opt[i] < 2) i++;
 		else i += opt[i+1]?:1;
@@ -1488,25 +1479,29 @@
 	  const struct net_device *out,
 	  const void *matchinfo,
 	  int offset,
-	  const void *hdr,
-	  u_int16_t datalen,
 	  int *hotdrop)
 {
-	const struct tcphdr *tcp = hdr;
+	struct tcphdr tcph;
 	const struct ipt_tcp *tcpinfo = matchinfo;
 
-	/* To quote Alan:
-
-	   Don't allow a fragment of TCP 8 bytes in. Nobody normal
-	   causes this. Its a cracker trying to break in by doing a
-	   flag overwrite to pass the direction checks.
-	*/
+	if (offset) {
+		/* To quote Alan:
 
-	if (offset == 1) {
-		duprintf("Dropping evil TCP offset=1 frag.\n");
-		*hotdrop = 1;
+		   Don't allow a fragment of TCP 8 bytes in. Nobody normal
+		   causes this. Its a cracker trying to break in by doing a
+		   flag overwrite to pass the direction checks.
+		*/
+		if (offset == 1) {
+			duprintf("Dropping evil TCP offset=1 frag.\n");
+			*hotdrop = 1;
+		}
+		/* Must not be a fragment. */
 		return 0;
-	} else if (offset == 0 && datalen < sizeof(struct tcphdr)) {
+	}
+
+#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
+
+	if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) {
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 		duprintf("Dropping evil TCP offset=0 tinygram.\n");
@@ -1514,27 +1509,24 @@
 		return 0;
 	}
 
-	/* FIXME: Try tcp doff >> packet len against various stacks --RR */
-
-#define FWINVTCP(bool,invflg) ((bool) ^ !!(tcpinfo->invflags & invflg))
-
-	/* Must not be a fragment. */
-	return !offset
-		&& port_match(tcpinfo->spts[0], tcpinfo->spts[1],
-			      ntohs(tcp->source),
-			      !!(tcpinfo->invflags & IPT_TCP_INV_SRCPT))
-		&& port_match(tcpinfo->dpts[0], tcpinfo->dpts[1],
-			      ntohs(tcp->dest),
-			      !!(tcpinfo->invflags & IPT_TCP_INV_DSTPT))
-		&& FWINVTCP((((unsigned char *)tcp)[13]
-			     & tcpinfo->flg_mask)
-			    == tcpinfo->flg_cmp,
-			    IPT_TCP_INV_FLAGS)
-		&& (!tcpinfo->option
-		    || tcp_find_option(tcpinfo->option, tcp, datalen,
-				       tcpinfo->invflags
-				       & IPT_TCP_INV_OPTION,
-				       hotdrop));
+	if (!port_match(tcpinfo->spts[0], tcpinfo->spts[1],
+			ntohs(tcph.source),
+			!!(tcpinfo->invflags & IPT_TCP_INV_SRCPT)))
+		return 0;
+	if (!port_match(tcpinfo->dpts[0], tcpinfo->dpts[1],
+			ntohs(tcph.dest),
+			!!(tcpinfo->invflags & IPT_TCP_INV_DSTPT)))
+		return 0;
+	if (!FWINVTCP((((unsigned char *)&tcph)[13] & tcpinfo->flg_mask)
+		      == tcpinfo->flg_cmp,
+		      IPT_TCP_INV_FLAGS))
+		return 0;
+	if (tcpinfo->option &&
+	    !tcp_find_option(tcpinfo->option, skb, tcph.doff*4 - sizeof(tcph),
+			     tcpinfo->invflags & IPT_TCP_INV_OPTION,
+			     hotdrop))
+		return 0;
+	return 1;
 }
 
 /* Called when user tries to insert an entry of this type. */
@@ -1560,14 +1552,16 @@
 	  const struct net_device *out,
 	  const void *matchinfo,
 	  int offset,
-	  const void *hdr,
-	  u_int16_t datalen,
 	  int *hotdrop)
 {
-	const struct udphdr *udp = hdr;
+	struct udphdr udph;
 	const struct ipt_udp *udpinfo = matchinfo;
 
-	if (offset == 0 && datalen < sizeof(struct udphdr)) {
+	/* Must not be a fragment. */
+	if (offset)
+		return 0;
+
+	if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &udph, sizeof(udph)) < 0) {
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 		duprintf("Dropping evil UDP tinygram.\n");
@@ -1575,13 +1569,11 @@
 		return 0;
 	}
 
-	/* Must not be a fragment. */
-	return !offset
-		&& port_match(udpinfo->spts[0], udpinfo->spts[1],
-			      ntohs(udp->source),
-			      !!(udpinfo->invflags & IPT_UDP_INV_SRCPT))
+	return port_match(udpinfo->spts[0], udpinfo->spts[1],
+			  ntohs(udph.source),
+			  !!(udpinfo->invflags & IPT_UDP_INV_SRCPT))
 		&& port_match(udpinfo->dpts[0], udpinfo->dpts[1],
-			      ntohs(udp->dest),
+			      ntohs(udph.dest),
 			      !!(udpinfo->invflags & IPT_UDP_INV_DSTPT));
 }
 
@@ -1631,14 +1623,16 @@
 	   const struct net_device *out,
 	   const void *matchinfo,
 	   int offset,
-	   const void *hdr,
-	   u_int16_t datalen,
 	   int *hotdrop)
 {
-	const struct icmphdr *icmp = hdr;
+	struct icmphdr icmph;
 	const struct ipt_icmp *icmpinfo = matchinfo;
 
-	if (offset == 0 && datalen < 2) {
+	/* Must not be a fragment. */
+	if (offset)
+		return 0;
+
+	if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &icmph, sizeof(icmph)) < 0){
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 		duprintf("Dropping evil ICMP tinygram.\n");
@@ -1646,13 +1640,11 @@
 		return 0;
 	}
 
-	/* Must not be a fragment. */
-	return !offset
-		&& icmp_type_code_match(icmpinfo->type,
-					icmpinfo->code[0],
-					icmpinfo->code[1],
-					icmp->type, icmp->code,
-					!!(icmpinfo->invflags&IPT_ICMP_INV));
+	return icmp_type_code_match(icmpinfo->type,
+				    icmpinfo->code[0],
+				    icmpinfo->code[1],
+				    icmph.type, icmph.code,
+				    !!(icmpinfo->invflags&IPT_ICMP_INV));
 }
 
 /* Called when user tries to insert an entry of this type. */
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_DSCP.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_DSCP.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_DSCP.c	2003-05-04 16:53:42.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_DSCP.c	2003-05-23 04:36:23.000000000 -0700
@@ -23,37 +23,31 @@
 
 static unsigned int
 target(struct sk_buff **pskb,
-       unsigned int hooknum,
        const struct net_device *in,
        const struct net_device *out,
+       unsigned int hooknum,
        const void *targinfo,
        void *userinfo)
 {
-	struct iphdr *iph = (*pskb)->nh.iph;
 	const struct ipt_DSCP_info *dinfo = targinfo;
 	u_int8_t sh_dscp = ((dinfo->dscp << IPT_DSCP_SHIFT) & IPT_DSCP_MASK);
 
 
-	if ((iph->tos & IPT_DSCP_MASK) != sh_dscp) {
+	if (((*pskb)->nh.iph->tos & IPT_DSCP_MASK) != sh_dscp) {
 		u_int16_t diffs[2];
 
-		/* raw socket (tcpdump) may have clone of incoming
-		 * skb: don't disturb it --RR */
-		if (skb_cloned(*pskb) && !(*pskb)->sk) {
-			struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
-			if (!nskb)
-				return NF_DROP;
-			kfree_skb(*pskb);
-			*pskb = nskb;
-			iph = (*pskb)->nh.iph;
-		}
-
-		diffs[0] = htons(iph->tos) ^ 0xFFFF;
-		iph->tos = (iph->tos & ~IPT_DSCP_MASK) | sh_dscp;
-		diffs[1] = htons(iph->tos);
-		iph->check = csum_fold(csum_partial((char *)diffs,
-		                                    sizeof(diffs),
-		                                    iph->check^0xFFFF));
+		if (!skb_ip_make_writable(pskb, sizeof(struct iphdr)))
+			return NF_DROP;
+
+		diffs[0] = htons((*pskb)->nh.iph->tos) ^ 0xFFFF;
+		(*pskb)->nh.iph->tos = ((*pskb)->nh.iph->tos & ~IPT_DSCP_MASK)
+			| sh_dscp;
+		diffs[1] = htons((*pskb)->nh.iph->tos);
+		(*pskb)->nh.iph->check
+			= csum_fold(csum_partial((char *)diffs,
+						 sizeof(diffs),
+						 (*pskb)->nh.iph->check
+						 ^ 0xFFFF));
 		(*pskb)->nfcache |= NFC_ALTERED;
 	}
 	return IPT_CONTINUE;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_ECN.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_ECN.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_ECN.c	2003-05-04 16:53:56.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_ECN.c	2003-05-23 04:36:23.000000000 -0700
@@ -19,105 +19,85 @@
 MODULE_LICENSE("GPL");
 
 /* set ECT codepoint from IP header.
- * 	return 0 in case there was no ECT codepoint
- * 	return 1 in case ECT codepoint has been overwritten
- * 	return < 0 in case there was error */
+ * 	return 0 if there was an error. */
 static inline int
-set_ect_ip(struct sk_buff **pskb, struct iphdr *iph,
-	   const struct ipt_ECN_info *einfo)
+set_ect_ip(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 {
-	if ((iph->tos & IPT_ECN_IP_MASK)
+	if (((*pskb)->nh.iph->tos & IPT_ECN_IP_MASK)
 	    != (einfo->ip_ect & IPT_ECN_IP_MASK)) {
 		u_int16_t diffs[2];
 
-		/* raw socket (tcpdump) may have clone of incoming
-		 * skb: don't disturb it --RR */
-		if (skb_cloned(*pskb) && !(*pskb)->sk) {
-			struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
-			if (!nskb)
-				return NF_DROP;
-			kfree_skb(*pskb);
-			*pskb = nskb;
-			iph = (*pskb)->nh.iph;
-		}
-
-		diffs[0] = htons(iph->tos) ^ 0xFFFF;
-		iph->tos = iph->tos & ~IPT_ECN_IP_MASK;
-		iph->tos = iph->tos | (einfo->ip_ect & IPT_ECN_IP_MASK);
-		diffs[1] = htons(iph->tos);
-		iph->check = csum_fold(csum_partial((char *)diffs,
-		                                    sizeof(diffs),
-		                                    iph->check^0xFFFF));
-		(*pskb)->nfcache |= NFC_ALTERED;
+		if (!skb_ip_make_writable(pskb, sizeof(struct iphdr)))
+			return 0;
 
-		return 1;
+		diffs[0] = htons((*pskb)->nh.iph->tos) ^ 0xFFFF;
+		(*pskb)->nh.iph->tos &= ~IPT_ECN_IP_MASK;
+		(*pskb)->nh.iph->tos |= (einfo->ip_ect & IPT_ECN_IP_MASK);
+		diffs[1] = htons((*pskb)->nh.iph->tos);
+		(*pskb)->nh.iph->check
+			= csum_fold(csum_partial((char *)diffs,
+						 sizeof(diffs),
+						 (*pskb)->nh.iph->check
+						 ^0xFFFF));
+		(*pskb)->nfcache |= NFC_ALTERED;
 	} 
-	return 0;
+	return 1;
 }
 
+/* Return 0 if there was an error. */
 static inline int
-set_ect_tcp(struct sk_buff **pskb, struct iphdr *iph,
-	    const struct ipt_ECN_info *einfo)
+set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo)
 {
-
-	struct tcphdr *tcph = (void *) iph + iph->ihl * 4;
-	u_int16_t *tcpflags = (u_int16_t *)tcph + 6;
+	struct tcphdr tcph;
 	u_int16_t diffs[2];
 
-	/* raw socket (tcpdump) may have clone of incoming
-	 * skb: don't disturb it --RR */
-	if (skb_cloned(*pskb) && !(*pskb)->sk) {
-		struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
-		if (!nskb)
-			return NF_DROP;
-		kfree_skb(*pskb);
-		*pskb = nskb;
-		iph = (*pskb)->nh.iph;
-	}
-
-	diffs[0] = *tcpflags;
+	/* Not enought header? */
+	if (skb_copy_bits(*pskb, (*pskb)->nh.iph->ihl*4, &tcph, sizeof(tcph))
+	    < 0)
+		return 0;
 
-	if (einfo->operation & IPT_ECN_OP_SET_ECE
-	    && tcph->ece != einfo->proto.tcp.ece) {
-		tcph->ece = einfo->proto.tcp.ece;
-	}
+	diffs[0] = ((u_int16_t *)&tcph)[6];
+	if (einfo->operation & IPT_ECN_OP_SET_ECE)
+		tcph.ece = einfo->proto.tcp.ece;
+
+	if (einfo->operation & IPT_ECN_OP_SET_CWR)
+		tcph.cwr = einfo->proto.tcp.cwr;
+	diffs[1] = ((u_int16_t *)&tcph)[6];
 
-	if (einfo->operation & IPT_ECN_OP_SET_CWR
-	    && tcph->cwr != einfo->proto.tcp.cwr) {
-		tcph->cwr = einfo->proto.tcp.cwr;
-	}
-	
-	if (diffs[0] != *tcpflags) {
+	/* Only mangle if it's changed. */
+	if (diffs[0] != diffs[1]) {
 		diffs[0] = diffs[0] ^ 0xFFFF;
-		diffs[1] = *tcpflags;
-		tcph->check = csum_fold(csum_partial((char *)diffs,
+		if (!skb_ip_make_writable(pskb,
+					  (*pskb)->nh.iph->ihl*4+sizeof(tcph)))
+			return 0;
+		tcph.check = csum_fold(csum_partial((char *)diffs,
 		                                    sizeof(diffs),
-		                                    tcph->check^0xFFFF));
+		                                    tcph.check^0xFFFF));
+		memcpy((*pskb)->data + (*pskb)->nh.iph->ihl*4,
+		       &tcph, sizeof(tcph));
 		(*pskb)->nfcache |= NFC_ALTERED;
-
-		return 1;
 	}
-
-	return 0;
+	return 1;
 }
 
 static unsigned int
 target(struct sk_buff **pskb,
-       unsigned int hooknum,
        const struct net_device *in,
        const struct net_device *out,
+       unsigned int hooknum,
        const void *targinfo,
        void *userinfo)
 {
-	struct iphdr *iph = (*pskb)->nh.iph;
 	const struct ipt_ECN_info *einfo = targinfo;
 
 	if (einfo->operation & IPT_ECN_OP_SET_IP)
-		set_ect_ip(pskb, iph, einfo);
+		if (!set_ect_ip(pskb, einfo))
+			return NF_DROP;
 
 	if (einfo->operation & (IPT_ECN_OP_SET_ECE | IPT_ECN_OP_SET_CWR)
-	    && iph->protocol == IPPROTO_TCP)
-		set_ect_tcp(pskb, iph, einfo);
+	    && (*pskb)->nh.iph->protocol == IPPROTO_TCP)
+		if (!set_ect_tcp(pskb, einfo))
+			return NF_DROP;
 
 	return IPT_CONTINUE;
 }
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_LOG.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_LOG.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_LOG.c	2003-05-04 16:53:40.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_LOG.c	2003-05-23 04:36:23.000000000 -0700
@@ -29,127 +29,151 @@
 
 /* One level of recursion won't kill us */
 static void dump_packet(const struct ipt_log_info *info,
-			struct iphdr *iph, unsigned int len, int recurse)
+			const struct sk_buff *skb,
+			unsigned int iphoff)
 {
-	void *protoh = (u_int32_t *)iph + iph->ihl;
-	unsigned int datalen = len - iph->ihl * 4;
+	struct iphdr iph;
+
+	if (skb_copy_bits(skb, iphoff, &iph, sizeof(iph)) < 0) {
+		printk("TRUNCATED");
+		return;
+	}
 
 	/* Important fields:
 	 * TOS, len, DF/MF, fragment offset, TTL, src, dst, options. */
 	/* Max length: 40 "SRC=255.255.255.255 DST=255.255.255.255 " */
 	printk("SRC=%u.%u.%u.%u DST=%u.%u.%u.%u ",
-	       NIPQUAD(iph->saddr), NIPQUAD(iph->daddr));
+	       NIPQUAD(iph.saddr), NIPQUAD(iph.daddr));
 
 	/* Max length: 46 "LEN=65535 TOS=0xFF PREC=0xFF TTL=255 ID=65535 " */
 	printk("LEN=%u TOS=0x%02X PREC=0x%02X TTL=%u ID=%u ",
-	       ntohs(iph->tot_len), iph->tos & IPTOS_TOS_MASK,
-	       iph->tos & IPTOS_PREC_MASK, iph->ttl, ntohs(iph->id));
+	       ntohs(iph.tot_len), iph.tos & IPTOS_TOS_MASK,
+	       iph.tos & IPTOS_PREC_MASK, iph.ttl, ntohs(iph.id));
 
 	/* Max length: 6 "CE DF MF " */
-	if (ntohs(iph->frag_off) & IP_CE)
+	if (ntohs(iph.frag_off) & IP_CE)
 		printk("CE ");
-	if (ntohs(iph->frag_off) & IP_DF)
+	if (ntohs(iph.frag_off) & IP_DF)
 		printk("DF ");
-	if (ntohs(iph->frag_off) & IP_MF)
+	if (ntohs(iph.frag_off) & IP_MF)
 		printk("MF ");
 
 	/* Max length: 11 "FRAG:65535 " */
-	if (ntohs(iph->frag_off) & IP_OFFSET)
-		printk("FRAG:%u ", ntohs(iph->frag_off) & IP_OFFSET);
+	if (ntohs(iph.frag_off) & IP_OFFSET)
+		printk("FRAG:%u ", ntohs(iph.frag_off) & IP_OFFSET);
 
 	if ((info->logflags & IPT_LOG_IPOPT)
-	    && iph->ihl * 4 != sizeof(struct iphdr)) {
-		unsigned int i;
+	    && iph.ihl * 4 != sizeof(struct iphdr)) {
+		unsigned char opt[4 * 15 - sizeof(struct iphdr)];
+		unsigned int i, optsize;
+
+		optsize = iph.ihl * 4 - sizeof(struct iphdr);
+		if (skb_copy_bits(skb, iphoff+sizeof(iph), opt, optsize) < 0) {
+			printk("TRUNCATED");
+			return;
+		}
 
 		/* Max length: 127 "OPT (" 15*4*2chars ") " */
 		printk("OPT (");
-		for (i = sizeof(struct iphdr); i < iph->ihl * 4; i++)
-			printk("%02X", ((u_int8_t *)iph)[i]);
+		for (i = 0; i < optsize; i++)
+			printk("%02X", opt[i]);
 		printk(") ");
 	}
 
-	switch (iph->protocol) {
+	switch (iph.protocol) {
 	case IPPROTO_TCP: {
-		struct tcphdr *tcph = protoh;
+		struct tcphdr tcph;
 
 		/* Max length: 10 "PROTO=TCP " */
 		printk("PROTO=TCP ");
 
-		if (ntohs(iph->frag_off) & IP_OFFSET)
+		if (ntohs(iph.frag_off) & IP_OFFSET)
 			break;
 
 		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		if (datalen < sizeof (*tcph)) {
-			printk("INCOMPLETE [%u bytes] ", datalen);
+		if (skb_copy_bits(skb, iphoff+iph.ihl*4, &tcph, sizeof(tcph))
+		    < 0) {
+			printk("INCOMPLETE [%u bytes] ",
+			       skb->len - iphoff - iph.ihl*4);
 			break;
 		}
 
 		/* Max length: 20 "SPT=65535 DPT=65535 " */
 		printk("SPT=%u DPT=%u ",
-		       ntohs(tcph->source), ntohs(tcph->dest));
+		       ntohs(tcph.source), ntohs(tcph.dest));
 		/* Max length: 30 "SEQ=4294967295 ACK=4294967295 " */
 		if (info->logflags & IPT_LOG_TCPSEQ)
 			printk("SEQ=%u ACK=%u ",
-			       ntohl(tcph->seq), ntohl(tcph->ack_seq));
+			       ntohl(tcph.seq), ntohl(tcph.ack_seq));
 		/* Max length: 13 "WINDOW=65535 " */
-		printk("WINDOW=%u ", ntohs(tcph->window));
+		printk("WINDOW=%u ", ntohs(tcph.window));
 		/* Max length: 9 "RES=0x3F " */
-		printk("RES=0x%02x ", (u_int8_t)(ntohl(tcp_flag_word(tcph) & TCP_RESERVED_BITS) >> 22));
+		printk("RES=0x%02x ", (u8)(ntohl(tcp_flag_word(&tcph) & TCP_RESERVED_BITS) >> 22));
 		/* Max length: 32 "CWR ECE URG ACK PSH RST SYN FIN " */
-		if (tcph->cwr)
+		if (tcph.cwr)
 			printk("CWR ");
-		if (tcph->ece)
+		if (tcph.ece)
 			printk("ECE ");
-		if (tcph->urg)
+		if (tcph.urg)
 			printk("URG ");
-		if (tcph->ack)
+		if (tcph.ack)
 			printk("ACK ");
-		if (tcph->psh)
+		if (tcph.psh)
 			printk("PSH ");
-		if (tcph->rst)
+		if (tcph.rst)
 			printk("RST ");
-		if (tcph->syn)
+		if (tcph.syn)
 			printk("SYN ");
-		if (tcph->fin)
+		if (tcph.fin)
 			printk("FIN ");
 		/* Max length: 11 "URGP=65535 " */
-		printk("URGP=%u ", ntohs(tcph->urg_ptr));
+		printk("URGP=%u ", ntohs(tcph.urg_ptr));
 
 		if ((info->logflags & IPT_LOG_TCPOPT)
-		    && tcph->doff * 4 != sizeof(struct tcphdr)) {
-			unsigned int i;
+		    && tcph.doff * 4 != sizeof(struct tcphdr)) {
+			unsigned char opt[4 * 15 - sizeof(struct tcphdr)];
+			unsigned int i, optsize;
+
+			optsize = tcph.doff * 4 - sizeof(struct tcphdr);
+			if (skb_copy_bits(skb, iphoff+iph.ihl*4 + sizeof(tcph),
+					  opt, optsize) < 0) {
+				printk("TRUNCATED");
+				return;
+			}
 
 			/* Max length: 127 "OPT (" 15*4*2chars ") " */
 			printk("OPT (");
-			for (i =sizeof(struct tcphdr); i < tcph->doff * 4; i++)
-				printk("%02X", ((u_int8_t *)tcph)[i]);
+			for (i = 0; i < optsize; i++)
+				printk("%02X", opt[i]);
 			printk(") ");
 		}
 		break;
 	}
 	case IPPROTO_UDP: {
-		struct udphdr *udph = protoh;
+		struct udphdr udph;
 
 		/* Max length: 10 "PROTO=UDP " */
 		printk("PROTO=UDP ");
 
-		if (ntohs(iph->frag_off) & IP_OFFSET)
+		if (ntohs(iph.frag_off) & IP_OFFSET)
 			break;
 
 		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		if (datalen < sizeof (*udph)) {
-			printk("INCOMPLETE [%u bytes] ", datalen);
+		if (skb_copy_bits(skb, iphoff+iph.ihl*4, &udph, sizeof(udph))
+		    < 0) {
+			printk("INCOMPLETE [%u bytes] ",
+			       skb->len - iphoff - iph.ihl*4);
 			break;
 		}
 
 		/* Max length: 20 "SPT=65535 DPT=65535 " */
 		printk("SPT=%u DPT=%u LEN=%u ",
-		       ntohs(udph->source), ntohs(udph->dest),
-		       ntohs(udph->len));
+		       ntohs(udph.source), ntohs(udph.dest),
+		       ntohs(udph.len));
 		break;
 	}
 	case IPPROTO_ICMP: {
-		struct icmphdr *icmph = protoh;
+		struct icmphdr icmph;
 		static size_t required_len[NR_ICMP_TYPES+1]
 			= { [ICMP_ECHOREPLY] = 4,
 			    [ICMP_DEST_UNREACH]
@@ -171,89 +195,93 @@
 		/* Max length: 11 "PROTO=ICMP " */
 		printk("PROTO=ICMP ");
 
-		if (ntohs(iph->frag_off) & IP_OFFSET)
+		if (ntohs(iph.frag_off) & IP_OFFSET)
 			break;
 
 		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		if (datalen < 4) {
-			printk("INCOMPLETE [%u bytes] ", datalen);
+		if (skb_copy_bits(skb, iphoff+iph.ihl*4, &icmph, sizeof(icmph))
+		    < 0) {
+			printk("INCOMPLETE [%u bytes] ",
+			       skb->len - iphoff - iph.ihl*4);
 			break;
 		}
 
 		/* Max length: 18 "TYPE=255 CODE=255 " */
-		printk("TYPE=%u CODE=%u ", icmph->type, icmph->code);
+		printk("TYPE=%u CODE=%u ", icmph.type, icmph.code);
 
 		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		if (icmph->type <= NR_ICMP_TYPES
-		    && required_len[icmph->type]
-		    && datalen < required_len[icmph->type]) {
-			printk("INCOMPLETE [%u bytes] ", datalen);
+		if (icmph.type <= NR_ICMP_TYPES
+		    && required_len[icmph.type]
+		    && skb->len-iphoff-iph.ihl*4 < required_len[icmph.type]) {
+			printk("INCOMPLETE [%u bytes] ",
+			       skb->len - iphoff - iph.ihl*4);
 			break;
 		}
 
-		switch (icmph->type) {
+		switch (icmph.type) {
 		case ICMP_ECHOREPLY:
 		case ICMP_ECHO:
 			/* Max length: 19 "ID=65535 SEQ=65535 " */
 			printk("ID=%u SEQ=%u ",
-			       ntohs(icmph->un.echo.id),
-			       ntohs(icmph->un.echo.sequence));
+			       ntohs(icmph.un.echo.id),
+			       ntohs(icmph.un.echo.sequence));
 			break;
 
 		case ICMP_PARAMETERPROB:
 			/* Max length: 14 "PARAMETER=255 " */
 			printk("PARAMETER=%u ",
-			       ntohl(icmph->un.gateway) >> 24);
+			       ntohl(icmph.un.gateway) >> 24);
 			break;
 		case ICMP_REDIRECT:
 			/* Max length: 24 "GATEWAY=255.255.255.255 " */
-			printk("GATEWAY=%u.%u.%u.%u ", NIPQUAD(icmph->un.gateway));
+			printk("GATEWAY=%u.%u.%u.%u ",
+			       NIPQUAD(icmph.un.gateway));
 			/* Fall through */
 		case ICMP_DEST_UNREACH:
 		case ICMP_SOURCE_QUENCH:
 		case ICMP_TIME_EXCEEDED:
 			/* Max length: 3+maxlen */
-			if (recurse) {
+			if (!iphoff) { /* Only recurse once. */
 				printk("[");
-				dump_packet(info,
-					    (struct iphdr *)(icmph + 1),
-					    datalen-sizeof(struct icmphdr),
-					    0);
+				dump_packet(info, skb,
+					    iphoff + iph.ihl*4+sizeof(icmph));
 				printk("] ");
 			}
 
 			/* Max length: 10 "MTU=65535 " */
-			if (icmph->type == ICMP_DEST_UNREACH
-			    && icmph->code == ICMP_FRAG_NEEDED)
-				printk("MTU=%u ", ntohs(icmph->un.frag.mtu));
+			if (icmph.type == ICMP_DEST_UNREACH
+			    && icmph.code == ICMP_FRAG_NEEDED)
+				printk("MTU=%u ", ntohs(icmph.un.frag.mtu));
 		}
 		break;
 	}
 	/* Max Length */
 	case IPPROTO_AH:
 	case IPPROTO_ESP: {
-		struct esphdr *esph = protoh;
-		int esp= (iph->protocol==IPPROTO_ESP);
+		struct esphdr esph;
+		int esp = (iph.protocol==IPPROTO_ESP);
 
 		/* Max length: 10 "PROTO=ESP " */
 		printk("PROTO=%s ",esp? "ESP" : "AH");
 
-		if (ntohs(iph->frag_off) & IP_OFFSET)
+		if (ntohs(iph.frag_off) & IP_OFFSET)
 			break;
 
 		/* Max length: 25 "INCOMPLETE [65535 bytes] " */
-		if (datalen < sizeof (*esph)) {
-			printk("INCOMPLETE [%u bytes] ", datalen);
+		if (skb_copy_bits(skb, iphoff+iph.ihl*4, &esph, sizeof(esph))
+		    < 0) {
+			printk("INCOMPLETE [%u bytes] ",
+			       skb->len - iphoff - iph.ihl*4);
 			break;
 		}
 
 		/* Length: 15 "SPI=0xF1234567 " */
-		printk("SPI=0x%x ", ntohl(esph->spi) );
+		printk("SPI=0x%x ", ntohl(esph.spi));
 		break;
 	}
 	/* Max length: 10 "PROTO 255 " */
 	default:
-		printk("PROTO=%u ", iph->protocol);
+		printk("PROTO=%u ", iph.protocol);
 	}
 
 	/* Proto    Max log string length */
@@ -272,13 +300,12 @@
 
 static unsigned int
 ipt_log_target(struct sk_buff **pskb,
-	       unsigned int hooknum,
 	       const struct net_device *in,
 	       const struct net_device *out,
+	       unsigned int hooknum,
 	       const void *targinfo,
 	       void *userinfo)
 {
-	struct iphdr *iph = (*pskb)->nh.iph;
 	const struct ipt_log_info *loginfo = targinfo;
 	char level_string[4] = "< >";
 
@@ -304,7 +331,8 @@
 	if (in && !out) {
 		/* MAC logging for input chain only. */
 		printk("MAC=");
-		if ((*pskb)->dev && (*pskb)->dev->hard_header_len && (*pskb)->mac.raw != (void*)iph) {
+		if ((*pskb)->dev && (*pskb)->dev->hard_header_len
+		    && (*pskb)->mac.raw != (void*)(*pskb)->nh.iph) {
 			int i;
 			unsigned char *p = (*pskb)->mac.raw;
 			for (i = 0; i < (*pskb)->dev->hard_header_len; i++,p++)
@@ -315,7 +343,7 @@
 			printk(" ");
 	}
 
-	dump_packet(loginfo, iph, (*pskb)->len, 1);
+	dump_packet(loginfo, *pskb, 0);
 	printk("\n");
 	spin_unlock_bh(&log_lock);
 
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_MARK.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_MARK.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_MARK.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_MARK.c	2003-05-23 04:36:23.000000000 -0700
@@ -9,9 +9,9 @@
 
 static unsigned int
 target(struct sk_buff **pskb,
-       unsigned int hooknum,
        const struct net_device *in,
        const struct net_device *out,
+       unsigned int hooknum,
        const void *targinfo,
        void *userinfo)
 {
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_MASQUERADE.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_MASQUERADE.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_MASQUERADE.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_MASQUERADE.c	2003-05-23 04:36:23.000000000 -0700
@@ -57,9 +57,9 @@
 
 static unsigned int
 masquerade_target(struct sk_buff **pskb,
-		  unsigned int hooknum,
 		  const struct net_device *in,
 		  const struct net_device *out,
+		  unsigned int hooknum,
 		  const void *targinfo,
 		  void *userinfo)
 {
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_MIRROR.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_MIRROR.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_MIRROR.c	2003-05-04 16:53:57.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_MIRROR.c	2003-05-23 04:36:23.000000000 -0700
@@ -65,18 +65,22 @@
 	return 0;
 }
 
-static void
-ip_rewrite(struct sk_buff *skb)
+static int ip_rewrite(struct sk_buff **pskb)
 {
-	struct iphdr *iph = skb->nh.iph;
-	u32 odaddr = iph->saddr;
-	u32 osaddr = iph->daddr;
+	u32 odaddr, osaddr;
 
-	skb->nfcache |= NFC_ALTERED;
+	if (!skb_ip_make_writable(pskb, sizeof(struct iphdr)))
+		return 0;
+
+	odaddr = (*pskb)->nh.iph->saddr;
+	osaddr = (*pskb)->nh.iph->daddr;
+
+	(*pskb)->nfcache |= NFC_ALTERED;
 
 	/* Rewrite IP header */
-	iph->daddr = odaddr;
-	iph->saddr = osaddr;
+	(*pskb)->nh.iph->daddr = odaddr;
+	(*pskb)->nh.iph->saddr = osaddr;
+	return 1;
 }
 
 /* Stolen from ip_finish_output2 */
@@ -100,29 +104,28 @@
 }
 
 static unsigned int ipt_mirror_target(struct sk_buff **pskb,
-				      unsigned int hooknum,
 				      const struct net_device *in,
 				      const struct net_device *out,
+				      unsigned int hooknum,
 				      const void *targinfo,
 				      void *userinfo)
 {
-	if (((*pskb)->dst != NULL) &&
-	    route_mirror(*pskb)) {
-
-		ip_rewrite(*pskb);
+	if (((*pskb)->dst != NULL) && route_mirror(*pskb)) {
+		if (!ip_rewrite(pskb))
+			return NF_DROP;
 
 		/* If we are not at FORWARD hook (INPUT/PREROUTING),
 		 * the TTL isn't decreased by the IP stack */
 		if (hooknum != NF_IP_FORWARD) {
-			struct iphdr *iph = (*pskb)->nh.iph;
-			if (iph->ttl <= 1) {
+			if ((*pskb)->nh.iph->ttl <= 1) {
 				/* this will traverse normal stack, and 
 				 * thus call conntrack on the icmp packet */
 				icmp_send(*pskb, ICMP_TIME_EXCEEDED, 
 					  ICMP_EXC_TTL, 0);
 				return NF_DROP;
 			}
-			ip_decrease_ttl(iph);
+			/* Made writable by ip_rewrite */
+			ip_decrease_ttl((*pskb)->nh.iph);
 		}
 
 		/* Don't let conntrack code see this packet:
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_REDIRECT.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_REDIRECT.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_REDIRECT.c	2003-05-04 16:53:09.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_REDIRECT.c	2003-05-23 04:36:23.000000000 -0700
@@ -53,9 +53,9 @@
 
 static unsigned int
 redirect_target(struct sk_buff **pskb,
-		unsigned int hooknum,
 		const struct net_device *in,
 		const struct net_device *out,
+		unsigned int hooknum,
 		const void *targinfo,
 		void *userinfo)
 {
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_REJECT.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_REJECT.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_REJECT.c	2003-05-04 16:53:37.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_REJECT.c	2003-05-23 04:36:23.000000000 -0700
@@ -29,152 +29,140 @@
 	void (*attach)(struct sk_buff *, struct nf_ct_info *);
 
 	/* Avoid module unload race with ip_ct_attach being NULLed out */
-	if (nfct && (attach = ip_ct_attach) != NULL)
+	if (nfct && (attach = ip_ct_attach) != NULL) {
+		mb(); /* Just to be sure: must be read before executing this */
 		attach(new_skb, nfct);
+	}
 }
 
 /* Send RST reply */
-static void send_reset(struct sk_buff *oldskb, int local)
+static unsigned int send_reset(struct sk_buff **pskb, int local)
 {
-	struct sk_buff *nskb;
-	struct tcphdr *otcph, *tcph;
+	struct tcphdr tcph;
 	struct rtable *rt;
-	unsigned int otcplen;
 	u_int16_t tmp_port;
 	u_int32_t tmp_addr;
-	int needs_ack;
-	int hh_len;
+	int needs_ack, hh_len, datalen;
+	struct nf_ct_info *oldnfct;
 
-	/* IP header checks: fragment, too short. */
-	if (oldskb->nh.iph->frag_off & htons(IP_OFFSET)
-	    || oldskb->len < (oldskb->nh.iph->ihl<<2) + sizeof(struct tcphdr))
-		return;
+	/* No RSTs for fragments. */
+	if ((*pskb)->nh.iph->frag_off & htons(IP_OFFSET))
+		return NF_DROP;
 
-	otcph = (struct tcphdr *)((u_int32_t*)oldskb->nh.iph + oldskb->nh.iph->ihl);
-	otcplen = oldskb->len - oldskb->nh.iph->ihl*4;
+	if (skb_copy_bits(*pskb, (*pskb)->nh.iph->ihl*4,
+			  &tcph, sizeof(tcph)) < 0)
+		return NF_DROP;
 
 	/* No RST for RST. */
-	if (otcph->rst)
-		return;
-
-	/* Check checksum. */
-	if (tcp_v4_check(otcph, otcplen, oldskb->nh.iph->saddr,
-			 oldskb->nh.iph->daddr,
-			 csum_partial((char *)otcph, otcplen, 0)) != 0)
-		return;
-
+	if (tcph.rst)
+		return NF_DROP;
 
+	/* FIXME: Check checksum. */
 	{
 		struct flowi fl = { .nl_u = { .ip4_u =
-					      { .daddr = oldskb->nh.iph->saddr,
+					      { .daddr = (*pskb)->nh.iph->saddr,
 						.saddr = (local ?
-							  oldskb->nh.iph->daddr :
+							  (*pskb)->nh.iph->daddr :
 							  0),
-						.tos = RT_TOS(oldskb->nh.iph->tos) } } };
+						.tos = RT_TOS((*pskb)->nh.iph->tos) } } };
 
 		/* Routing: if not headed for us, route won't like source */
 		if (ip_route_output_key(&rt, &fl))
-			return;
-	
+			return NF_DROP;
+
 		hh_len = (rt->u.dst.dev->hard_header_len + 15)&~15;
 	}
 
-
-	/* Copy skb (even if skb is about to be dropped, we can't just
-           clone it because there may be other things, such as tcpdump,
-           interested in it). We also need to expand headroom in case
-	   hh_len of incoming interface < hh_len of outgoing interface */
-	nskb = skb_copy_expand(oldskb, hh_len, skb_tailroom(oldskb),
-			       GFP_ATOMIC);
-	if (!nskb) {
-		dst_release(&rt->u.dst);
-		return;
+	/* We're going to flip the header around, drop options and data. */
+	if (!skb_ip_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(tcph))) {
+		ip_rt_put(rt);
+		return NF_DROP;
 	}
 
-	dst_release(nskb->dst);
-	nskb->dst = &rt->u.dst;
+	(*pskb)->h.th = (void *)(*pskb)->nh.iph + sizeof(tcph);
+	datalen = (*pskb)->len - (*pskb)->nh.iph->ihl*4 - tcph.doff*4;
+
+	/* Change over route. */
+	dst_release((*pskb)->dst);
+	(*pskb)->dst = &rt->u.dst;
 
 	/* This packet will not be the same as the other: clear nf fields */
-	nf_conntrack_put(nskb->nfct);
-	nskb->nfct = NULL;
-	nskb->nfcache = 0;
+	(*pskb)->nfcache = 0;
 #ifdef CONFIG_NETFILTER_DEBUG
-	nskb->nf_debug = 0;
+	(*pskb)->nf_debug = 0;
 #endif
-	nskb->nfmark = 0;
-
-	tcph = (struct tcphdr *)((u_int32_t*)nskb->nh.iph + nskb->nh.iph->ihl);
+	(*pskb)->nfmark = 0;
 
 	/* Swap source and dest */
-	tmp_addr = nskb->nh.iph->saddr;
-	nskb->nh.iph->saddr = nskb->nh.iph->daddr;
-	nskb->nh.iph->daddr = tmp_addr;
-	tmp_port = tcph->source;
-	tcph->source = tcph->dest;
-	tcph->dest = tmp_port;
+	tmp_addr = (*pskb)->nh.iph->saddr;
+	(*pskb)->nh.iph->saddr = (*pskb)->nh.iph->daddr;
+	(*pskb)->nh.iph->daddr = tmp_addr;
+	tmp_port = (*pskb)->h.th->source;
+	(*pskb)->h.th->source = (*pskb)->h.th->dest;
+	(*pskb)->h.th->dest = tmp_port;
 
 	/* Truncate to length (no data) */
-	tcph->doff = sizeof(struct tcphdr)/4;
-	skb_trim(nskb, nskb->nh.iph->ihl*4 + sizeof(struct tcphdr));
-	nskb->nh.iph->tot_len = htons(nskb->len);
+	(*pskb)->h.th->doff = sizeof(struct tcphdr)/4;
+	skb_trim(*pskb, (*pskb)->nh.iph->ihl*4 + sizeof(struct tcphdr));
+	(*pskb)->nh.iph->tot_len = htons((*pskb)->len);
 
-	if (tcph->ack) {
+	if ((*pskb)->h.th->ack) {
 		needs_ack = 0;
-		tcph->seq = otcph->ack_seq;
-		tcph->ack_seq = 0;
+		(*pskb)->h.th->seq = tcph.ack_seq;
+		(*pskb)->h.th->ack_seq = 0;
 	} else {
 		needs_ack = 1;
-		tcph->ack_seq = htonl(ntohl(otcph->seq) + otcph->syn + otcph->fin
-				      + otcplen - (otcph->doff<<2));
-		tcph->seq = 0;
+		(*pskb)->h.th->ack_seq = htonl(ntohl(tcph.seq)
+						 + tcph.syn + tcph.fin
+						 + datalen);
+		(*pskb)->h.th->seq = 0;
 	}
 
 	/* Reset flags */
-	((u_int8_t *)tcph)[13] = 0;
-	tcph->rst = 1;
-	tcph->ack = needs_ack;
+	memset((*pskb)->h.raw + 13, 0, 1);
+	(*pskb)->h.th->rst = 1;
+	(*pskb)->h.th->ack = needs_ack;
 
-	tcph->window = 0;
-	tcph->urg_ptr = 0;
+	(*pskb)->h.th->window = 0;
+	(*pskb)->h.th->urg_ptr = 0;
 
 	/* Adjust TCP checksum */
-	tcph->check = 0;
-	tcph->check = tcp_v4_check(tcph, sizeof(struct tcphdr),
-				   nskb->nh.iph->saddr,
-				   nskb->nh.iph->daddr,
-				   csum_partial((char *)tcph,
-						sizeof(struct tcphdr), 0));
+	(*pskb)->h.th->check = 0;
+	(*pskb)->h.th->check
+		= tcp_v4_check((*pskb)->h.th,
+			       sizeof(struct tcphdr),
+			       (*pskb)->nh.iph->saddr,
+			       (*pskb)->nh.iph->daddr,
+			       csum_partial((*pskb)->h.raw,
+					    sizeof(struct tcphdr), 0));
 
 	/* Adjust IP TTL, DF */
-	nskb->nh.iph->ttl = MAXTTL;
+	(*pskb)->nh.iph->ttl = MAXTTL;
 	/* Set DF, id = 0 */
-	nskb->nh.iph->frag_off = htons(IP_DF);
-	nskb->nh.iph->id = 0;
+	(*pskb)->nh.iph->frag_off = htons(IP_DF);
+	(*pskb)->nh.iph->id = 0;
 
 	/* Adjust IP checksum */
-	nskb->nh.iph->check = 0;
-	nskb->nh.iph->check = ip_fast_csum((unsigned char *)nskb->nh.iph, 
-					   nskb->nh.iph->ihl);
+	(*pskb)->nh.iph->check = 0;
+	(*pskb)->nh.iph->check = ip_fast_csum((*pskb)->nh.raw, 
+					      (*pskb)->nh.iph->ihl);
 
 	/* "Never happens" */
-	if (nskb->len > dst_pmtu(nskb->dst))
-		goto free_nskb;
+	if ((*pskb)->len > dst_pmtu((*pskb)->dst))
+		return NF_DROP;
 
-	connection_attach(nskb, oldskb->nfct);
+	/* Related to old connection. */
+	oldnfct = (*pskb)->nfct;
+	connection_attach(*pskb, oldnfct);
+	nf_conntrack_put(oldnfct);
 
-	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, nskb, NULL, nskb->dst->dev,
+	NF_HOOK(PF_INET, NF_IP_LOCAL_OUT, *pskb, NULL, (*pskb)->dst->dev,
 		ip_finish_output);
-	return;
-
- free_nskb:
-	kfree_skb(nskb);
+	return NF_STOLEN;
 }
 
-static void send_unreach(struct sk_buff *skb_in, int code)
+static void send_unreach(const struct sk_buff *skb_in, int code)
 {
-	struct iphdr *iph;
-	struct udphdr *udph;
-	struct icmphdr *icmph;
 	struct sk_buff *nskb;
 	u32 saddr;
 	u8 tos;
@@ -189,8 +177,6 @@
 	if (!xrlim_allow(&rt->u.dst, 1*HZ))
 		return;
 
-	iph = skb_in->nh.iph;
-
 	/* No replies to physical multicast/broadcast */
 	if (skb_in->pkt_type!=PACKET_HOST)
 		return;
@@ -200,46 +186,41 @@
 		return;
 
 	/* Only reply to fragment 0. */
-	if (iph->frag_off&htons(IP_OFFSET))
+	if (skb_in->nh.iph->frag_off&htons(IP_OFFSET))
+		return;
+
+	/* Ensure we have at least 8 bytes of proto header. */
+	if (skb_in->len < skb_in->nh.iph->ihl*4 + 8)
 		return;
 
-	/* if UDP checksum is set, verify it's correct */
-	if (iph->protocol == IPPROTO_UDP
-	    && skb_in->tail-(u8*)iph >= sizeof(struct udphdr)) {
-		int datalen = skb_in->len - (iph->ihl<<2);
-		udph = (struct udphdr *)((char *)iph + (iph->ihl<<2));
-		if (udph->check
-		    && csum_tcpudp_magic(iph->saddr, iph->daddr,
-		                         datalen, IPPROTO_UDP,
-		                         csum_partial((char *)udph, datalen,
-		                                      0)) != 0)
-			return;
-	}
-		    
 	/* If we send an ICMP error to an ICMP error a mess would result.. */
-	if (iph->protocol == IPPROTO_ICMP
-	    && skb_in->tail-(u8*)iph >= sizeof(struct icmphdr)) {
-		icmph = (struct icmphdr *)((char *)iph + (iph->ihl<<2));
+	if (skb_in->nh.iph->protocol == IPPROTO_ICMP) {
+		struct icmphdr icmph;
+
+		if (skb_copy_bits(skb_in, skb_in->nh.iph->ihl*4,
+				  &icmph, sizeof(icmph)) < 0)
+			return;
+
 		/* Between echo-reply (0) and timestamp (13),
 		   everything except echo-request (8) is an error.
 		   Also, anything greater than NR_ICMP_TYPES is
 		   unknown, and hence should be treated as an error... */
-		if ((icmph->type < ICMP_TIMESTAMP
-		     && icmph->type != ICMP_ECHOREPLY
-		     && icmph->type != ICMP_ECHO)
-		    || icmph->type > NR_ICMP_TYPES)
+		if ((icmph.type < ICMP_TIMESTAMP
+		     && icmph.type != ICMP_ECHOREPLY
+		     && icmph.type != ICMP_ECHO)
+		    || icmph.type > NR_ICMP_TYPES)
 			return;
 	}
 
-	saddr = iph->daddr;
+	saddr = skb_in->nh.iph->daddr;
 	if (!(rt->rt_flags & RTCF_LOCAL))
 		saddr = 0;
 
-	tos = (iph->tos & IPTOS_TOS_MASK) | IPTOS_PREC_INTERNETCONTROL;
-
+	tos = (skb_in->nh.iph->tos & IPTOS_TOS_MASK)
+		| IPTOS_PREC_INTERNETCONTROL;
 	{
 		struct flowi fl = { .nl_u = { .ip4_u =
-					      { .daddr = iph->saddr,
+					      { .daddr = skb_in->nh.iph->saddr,
 						.saddr = saddr,
 						.tos = RT_TOS(tos) } } };
 		if (ip_route_output_key(&rt, &fl))
@@ -266,40 +247,38 @@
 	skb_reserve(nskb, hh_len);
 
 	/* Set up IP header */
-	iph = nskb->nh.iph
-		= (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
-	iph->version=4;
-	iph->ihl=5;
-	iph->tos=tos;
-	iph->tot_len = htons(length);
+	nskb->nh.iph = (struct iphdr *)skb_put(nskb, sizeof(struct iphdr));
+	nskb->nh.iph->version=4;
+	nskb->nh.iph->ihl=5;
+	nskb->nh.iph->tos=tos;
+	nskb->nh.iph->tot_len = htons(length);
 
 	/* PMTU discovery never applies to ICMP packets. */
-	iph->frag_off = 0;
+	nskb->nh.iph->frag_off = 0;
 
-	iph->ttl = MAXTTL;
-	ip_select_ident(iph, &rt->u.dst, NULL);
-	iph->protocol=IPPROTO_ICMP;
-	iph->saddr=rt->rt_src;
-	iph->daddr=rt->rt_dst;
-	iph->check=0;
-	iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl);
+	nskb->nh.iph->ttl = MAXTTL;
+	ip_select_ident(nskb->nh.iph, &rt->u.dst, NULL);
+	nskb->nh.iph->protocol=IPPROTO_ICMP;
+	nskb->nh.iph->saddr=rt->rt_src;
+	nskb->nh.iph->daddr=rt->rt_dst;
+	nskb->nh.iph->check=0;
+	nskb->nh.iph->check = ip_fast_csum(nskb->nh.raw,
+					   nskb->nh.iph->ihl);
 
 	/* Set up ICMP header. */
-	icmph = nskb->h.icmph
-		= (struct icmphdr *)skb_put(nskb, sizeof(struct icmphdr));
-	icmph->type = ICMP_DEST_UNREACH;
-	icmph->code = code;	
-	icmph->un.gateway = 0;
-	icmph->checksum = 0;
+	nskb->h.icmph = (struct icmphdr *)skb_put(nskb,sizeof(struct icmphdr));
+	nskb->h.icmph->type = ICMP_DEST_UNREACH;
+	nskb->h.icmph->code = code;	
+	nskb->h.icmph->un.gateway = 0;
+	nskb->h.icmph->checksum = 0;
 	
 	/* Copy as much of original packet as will fit */
 	data = skb_put(nskb,
 		       length - sizeof(struct iphdr) - sizeof(struct icmphdr));
-	/* FIXME: won't work with nonlinear skbs --RR */
-	memcpy(data, skb_in->nh.iph,
-	       length - sizeof(struct iphdr) - sizeof(struct icmphdr));
-	icmph->checksum = ip_compute_csum((unsigned char *)icmph,
-					  length - sizeof(struct iphdr));
+	skb_copy_bits(skb_in, 0, data,
+		      length - sizeof(struct iphdr) - sizeof(struct icmphdr));
+	nskb->h.icmph->checksum = ip_compute_csum(nskb->h.raw,
+						  length-sizeof(struct iphdr));
 
 	connection_attach(nskb, skb_in->nfct);
 
@@ -308,9 +287,9 @@
 }	
 
 static unsigned int reject(struct sk_buff **pskb,
-			   unsigned int hooknum,
 			   const struct net_device *in,
 			   const struct net_device *out,
+			   unsigned int hooknum,
 			   const void *targinfo,
 			   void *userinfo)
 {
@@ -344,7 +323,7 @@
     		send_unreach(*pskb, ICMP_HOST_ANO);
     		break;
 	case IPT_TCP_RESET:
-		send_reset(*pskb, hooknum == NF_IP_LOCAL_IN);
+		return send_reset(pskb, hooknum == NF_IP_LOCAL_IN);
 	case IPT_ICMP_ECHOREPLY:
 		/* Doesn't happen. */
 		break;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_TCPMSS.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_TCPMSS.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_TCPMSS.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_TCPMSS.c	2003-05-23 04:36:23.000000000 -0700
@@ -36,9 +36,9 @@
 
 static unsigned int
 ipt_tcpmss_target(struct sk_buff **pskb,
-		  unsigned int hooknum,
 		  const struct net_device *in,
 		  const struct net_device *out,
+		  unsigned int hooknum,
 		  const void *targinfo,
 		  void *userinfo)
 {
@@ -49,15 +49,8 @@
 	unsigned int i;
 	u_int8_t *opt;
 
-	/* raw socket (tcpdump) may have clone of incoming skb: don't
-	   disturb it --RR */
-	if (skb_cloned(*pskb) && !(*pskb)->sk) {
-		struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
-		if (!nskb)
-			return NF_DROP;
-		kfree_skb(*pskb);
-		*pskb = nskb;
-	}
+	if (!skb_ip_make_writable(pskb, (*pskb)->len))
+		return NF_DROP;
 
 	iph = (*pskb)->nh.iph;
 	tcplen = (*pskb)->len - iph->ihl*4;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_TOS.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_TOS.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_TOS.c	2003-05-04 16:53:00.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_TOS.c	2003-05-23 04:36:23.000000000 -0700
@@ -9,35 +9,30 @@
 
 static unsigned int
 target(struct sk_buff **pskb,
-       unsigned int hooknum,
        const struct net_device *in,
        const struct net_device *out,
+       unsigned int hooknum,
        const void *targinfo,
        void *userinfo)
 {
-	struct iphdr *iph = (*pskb)->nh.iph;
 	const struct ipt_tos_target_info *tosinfo = targinfo;
 
-	if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
+	if (((*pskb)->nh.iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
 		u_int16_t diffs[2];
 
-		/* raw socket (tcpdump) may have clone of incoming
-                   skb: don't disturb it --RR */
-		if (skb_cloned(*pskb) && !(*pskb)->sk) {
-			struct sk_buff *nskb = skb_copy(*pskb, GFP_ATOMIC);
-			if (!nskb)
-				return NF_DROP;
-			kfree_skb(*pskb);
-			*pskb = nskb;
-			iph = (*pskb)->nh.iph;
-		}
-
-		diffs[0] = htons(iph->tos) ^ 0xFFFF;
-		iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
-		diffs[1] = htons(iph->tos);
-		iph->check = csum_fold(csum_partial((char *)diffs,
-		                                    sizeof(diffs),
-		                                    iph->check^0xFFFF));
+		if (!skb_ip_make_writable(pskb, sizeof(struct iphdr)))
+			return NF_DROP;
+
+		diffs[0] = htons((*pskb)->nh.iph->tos) ^ 0xFFFF;
+		(*pskb)->nh.iph->tos
+			= ((*pskb)->nh.iph->tos & IPTOS_PREC_MASK)
+			| tosinfo->tos;
+		diffs[1] = htons((*pskb)->nh.iph->tos);
+		(*pskb)->nh.iph->check
+			= csum_fold(csum_partial((char *)diffs,
+						 sizeof(diffs),
+						 (*pskb)->nh.iph->check
+						 ^0xFFFF));
 		(*pskb)->nfcache |= NFC_ALTERED;
 	}
 	return IPT_CONTINUE;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_ULOG.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_ULOG.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_ULOG.c	2003-05-04 16:53:09.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_ULOG.c	2003-05-23 04:36:23.000000000 -0700
@@ -155,9 +155,9 @@
 }
 
 static unsigned int ipt_ulog_target(struct sk_buff **pskb,
-				    unsigned int hooknum,
 				    const struct net_device *in,
 				    const struct net_device *out,
+				    unsigned int hooknum,
 				    const void *targinfo, void *userinfo)
 {
 	ulog_buff_t *ub;
@@ -238,8 +238,9 @@
 	else
 		pm->outdev_name[0] = '\0';
 
-	if (copy_len)
-		memcpy(pm->payload, (*pskb)->data, copy_len);
+	/* copy_len <= (*pskb)->len, so can't fail. */
+	if (skb_copy_bits(*pskb, 0, pm->payload, copy_len) < 0)
+		BUG();
 	
 	/* check if we are building multi-part messages */
 	if (ub->qlen > 1) {
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_ah.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_ah.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_ah.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_ah.c	2003-05-23 04:36:23.000000000 -0700
@@ -35,14 +35,16 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
-	const struct ahhdr *ah = hdr;
+	struct ahhdr ah;
 	const struct ipt_ah *ahinfo = matchinfo;
 
-	if (offset == 0 && datalen < sizeof(struct ahhdr)) {
+	/* Must not be a fragment. */
+	if (offset)
+		return 0;
+
+	if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &ah, sizeof(ah)) < 0) {
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 		duprintf("Dropping evil AH tinygram.\n");
@@ -50,11 +52,9 @@
 		return 0;
 	}
 
-	/* Must not be a fragment. */
-	return !offset
-		&& spi_match(ahinfo->spis[0], ahinfo->spis[1],
-			      ntohl(ah->spi),
-			      !!(ahinfo->invflags & IPT_AH_INV_SPI));
+	return spi_match(ahinfo->spis[0], ahinfo->spis[1],
+			 ntohl(ah.spi),
+			 !!(ahinfo->invflags & IPT_AH_INV_SPI));
 }
 
 /* Called when user tries to insert an entry of this type. */
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_conntrack.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_conntrack.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_conntrack.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_conntrack.c	2003-05-23 04:36:23.000000000 -0700
@@ -14,8 +14,6 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
 	const struct ipt_conntrack_info *sinfo = matchinfo;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_dscp.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_dscp.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_dscp.c	2003-05-04 16:53:35.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_dscp.c	2003-05-23 04:36:23.000000000 -0700
@@ -19,8 +19,7 @@
 
 static int match(const struct sk_buff *skb, const struct net_device *in,
 		 const struct net_device *out, const void *matchinfo,
-		 int offset, const void *hdr, u_int16_t datalen,
-		 int *hotdrop)
+		 int offset, int *hotdrop)
 {
 	const struct ipt_dscp_info *info = matchinfo;
 	const struct iphdr *iph = skb->nh.iph;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_ecn.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_ecn.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_ecn.c	2003-05-04 16:53:14.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_ecn.c	2003-05-23 04:36:23.000000000 -0700
@@ -19,34 +19,40 @@
 MODULE_LICENSE("GPL");
 
 static inline int match_ip(const struct sk_buff *skb,
-			   const struct iphdr *iph,
 			   const struct ipt_ecn_info *einfo)
 {
-	return ((iph->tos&IPT_ECN_IP_MASK) == einfo->ip_ect);
+	return ((skb->nh.iph->tos&IPT_ECN_IP_MASK) == einfo->ip_ect);
 }
 
 static inline int match_tcp(const struct sk_buff *skb,
-			    const struct iphdr *iph,
-			    const struct ipt_ecn_info *einfo)
+			    const struct ipt_ecn_info *einfo,
+			    int *hotdrop)
 {
-	struct tcphdr *tcph = (void *)iph + iph->ihl*4;
+	struct tcphdr tcph;
+
+	/* In practice, TCP match does this, so can't fail.  But let's
+           be good citizens. */
+	if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0) {
+		*hotdrop = 0;
+		return 0;
+	}
 
 	if (einfo->operation & IPT_ECN_OP_MATCH_ECE) {
 		if (einfo->invert & IPT_ECN_OP_MATCH_ECE) {
-			if (tcph->ece == 1)
+			if (tcph.ece == 1)
 				return 0;
 		} else {
-			if (tcph->ece == 0)
+			if (tcph.ece == 0)
 				return 0;
 		}
 	}
 
 	if (einfo->operation & IPT_ECN_OP_MATCH_CWR) {
 		if (einfo->invert & IPT_ECN_OP_MATCH_CWR) {
-			if (tcph->cwr == 1)
+			if (tcph.cwr == 1)
 				return 0;
 		} else {
-			if (tcph->cwr == 0)
+			if (tcph.cwr == 0)
 				return 0;
 		}
 	}
@@ -56,20 +62,18 @@
 
 static int match(const struct sk_buff *skb, const struct net_device *in,
 		 const struct net_device *out, const void *matchinfo,
-		 int offset, const void *hdr, u_int16_t datalen,
-		 int *hotdrop)
+		 int offset, int *hotdrop)
 {
 	const struct ipt_ecn_info *info = matchinfo;
-	const struct iphdr *iph = skb->nh.iph;
 
 	if (info->operation & IPT_ECN_OP_MATCH_IP)
-		if (!match_ip(skb, iph, info))
+		if (!match_ip(skb, info))
 			return 0;
 
 	if (info->operation & (IPT_ECN_OP_MATCH_ECE|IPT_ECN_OP_MATCH_CWR)) {
-		if (iph->protocol != IPPROTO_TCP)
+		if (skb->nh.iph->protocol != IPPROTO_TCP)
 			return 0;
-		if (!match_tcp(skb, iph, info))
+		if (!match_tcp(skb, info, hotdrop))
 			return 0;
 	}
 
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_esp.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_esp.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_esp.c	2003-05-04 16:53:31.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_esp.c	2003-05-23 04:36:23.000000000 -0700
@@ -35,14 +35,16 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
-	const struct esphdr *esp = hdr;
+	struct esphdr esp;
 	const struct ipt_esp *espinfo = matchinfo;
 
-	if (offset == 0 && datalen < sizeof(struct esphdr)) {
+	/* Must not be a fragment. */
+	if (offset)
+		return 0;
+
+	if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &esp, sizeof(esp)) < 0) {
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 		duprintf("Dropping evil ESP tinygram.\n");
@@ -50,11 +52,9 @@
 		return 0;
 	}
 
-	/* Must not be a fragment. */
-	return !offset
-		&& spi_match(espinfo->spis[0], espinfo->spis[1],
-			      ntohl(esp->spi),
-			      !!(espinfo->invflags & IPT_ESP_INV_SPI));
+	return spi_match(espinfo->spis[0], espinfo->spis[1],
+			 ntohl(esp.spi),
+			 !!(espinfo->invflags & IPT_ESP_INV_SPI));
 }
 
 /* Called when user tries to insert an entry of this type. */
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_helper.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_helper.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_helper.c	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_helper.c	2003-05-23 04:36:23.000000000 -0700
@@ -28,8 +28,6 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
 	const struct ipt_helper_info *info = matchinfo;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_length.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_length.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_length.c	2003-05-04 16:53:36.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_length.c	2003-05-23 04:36:23.000000000 -0700
@@ -15,8 +15,6 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
 	const struct ipt_length_info *info = matchinfo;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_limit.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_limit.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_limit.c	2003-05-04 16:53:00.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_limit.c	2003-05-23 04:36:23.000000000 -0700
@@ -47,8 +47,6 @@
 		const struct net_device *out,
 		const void *matchinfo,
 		int offset,
-		const void *hdr,
-		u_int16_t datalen,
 		int *hotdrop)
 {
 	struct ipt_rateinfo *r = ((struct ipt_rateinfo *)matchinfo)->master;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_mac.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_mac.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_mac.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_mac.c	2003-05-23 04:36:23.000000000 -0700
@@ -12,8 +12,6 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
     const struct ipt_mac_info *info = matchinfo;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_mark.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_mark.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_mark.c	2003-05-04 16:53:57.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_mark.c	2003-05-23 04:36:23.000000000 -0700
@@ -11,8 +11,6 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
 	const struct ipt_mark_info *info = matchinfo;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_multiport.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_multiport.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_multiport.c	2003-05-04 16:53:03.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_multiport.c	2003-05-23 04:36:23.000000000 -0700
@@ -39,15 +39,18 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
-	const struct udphdr *udp = hdr;
+	u16 ports[2];
 	const struct ipt_multiport *multiinfo = matchinfo;
 
-	/* Must be big enough to read ports. */
-	if (offset == 0 && datalen < sizeof(struct udphdr)) {
+	/* Must not be a fragment. */
+	if (offset)
+		return 0;
+
+	/* Must be big enough to read ports (both UDP and TCP have
+           them at the start). */
+	if (skb_copy_bits(skb, skb->nh.iph->ihl*4, ports, sizeof(ports)) < 0) {
 		/* We've been asked to examine this packet, and we
 		   can't.  Hence, no choice but to drop. */
 			duprintf("ipt_multiport:"
@@ -56,11 +59,9 @@
 			return 0;
 	}
 
-	/* Must not be a fragment. */
-	return !offset
-		&& ports_match(multiinfo->ports,
-			       multiinfo->flags, multiinfo->count,
-			       ntohs(udp->source), ntohs(udp->dest));
+	return ports_match(multiinfo->ports,
+			   multiinfo->flags, multiinfo->count,
+			   ntohs(ports[0]), ntohs(ports[1]));
 }
 
 /* Called when user tries to insert an entry of this type. */
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_owner.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_owner.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_owner.c	2003-05-04 16:53:41.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_owner.c	2003-05-23 04:36:23.000000000 -0700
@@ -115,8 +115,6 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
 	const struct ipt_owner_info *info = matchinfo;
@@ -170,8 +168,11 @@
                 return 0;
         }
 
-	if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info)))
+	if (matchsize != IPT_ALIGN(sizeof(struct ipt_owner_info))) {
+		printk("Matchsize %u != %Zu\n", matchsize,
+		       IPT_ALIGN(sizeof(struct ipt_owner_info)));
 		return 0;
+	}
 
 	return 1;
 }
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_physdev.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_physdev.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_physdev.c	2003-05-04 16:53:08.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_physdev.c	2003-05-23 04:36:23.000000000 -0700
@@ -14,8 +14,6 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
 	int i;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_pkttype.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_pkttype.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_pkttype.c	2003-05-04 16:52:48.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_pkttype.c	2003-05-23 04:36:23.000000000 -0700
@@ -13,8 +13,6 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
     const struct ipt_pkttype_info *info = matchinfo;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_state.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_state.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_state.c	2003-05-04 16:53:57.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_state.c	2003-05-23 04:36:23.000000000 -0700
@@ -13,8 +13,6 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
 	const struct ipt_state_info *sinfo = matchinfo;
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_tcpmss.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_tcpmss.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_tcpmss.c	2003-05-04 16:53:02.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_tcpmss.c	2003-05-23 04:36:23.000000000 -0700
@@ -11,24 +11,32 @@
 /* Returns 1 if the mss option is set and matched by the range, 0 otherwise */
 static inline int
 mssoption_match(u_int16_t min, u_int16_t max,
-		const struct tcphdr *tcp,
-		u_int16_t datalen,
+		const struct sk_buff *skb,
 		int invert,
 		int *hotdrop)
 {
-	unsigned int i;
-	const u_int8_t *opt = (u_int8_t *)tcp;
+	struct tcphdr tcph;
+	/* tcp.doff is only 4 bits, ie. max 15 * 4 bytes */
+	u8 opt[15 * 4 - sizeof(tcph)];
+	unsigned int i, optlen;
 
 	/* If we don't have the whole header, drop packet. */
-	if (tcp->doff * 4 > datalen) {
-		*hotdrop = 1;
-		return 0;
-	}
+	if (skb_copy_bits(skb, skb->nh.iph->ihl*4, &tcph, sizeof(tcph)) < 0)
+		goto dropit;
 
-	for (i = sizeof(struct tcphdr); i < tcp->doff * 4; ) {
-		if ((opt[i] == TCPOPT_MSS)
-		    && ((tcp->doff * 4 - i) >= TCPOLEN_MSS)
-		    && (opt[i+1] == TCPOLEN_MSS)) {
+	/* Malformed. */
+	if (tcph.doff*4 < sizeof(tcph))
+		goto dropit;
+
+	optlen = tcph.doff*4 - sizeof(tcph);
+	/* Truncated options. */
+	if (skb_copy_bits(skb, skb->nh.iph->ihl*4+sizeof(tcph), opt, optlen)<0)
+		goto dropit;
+
+	for (i = 0; i < optlen; ) {
+		if (opt[i] == TCPOPT_MSS
+		    && (optlen - i) >= TCPOLEN_MSS
+		    && opt[i+1] == TCPOLEN_MSS) {
 			u_int16_t mssval;
 
 			mssval = (opt[i+2] << 8) | opt[i+3];
@@ -38,8 +46,11 @@
 		if (opt[i] < 2) i++;
 		else i += opt[i+1]?:1;
 	}
-
 	return invert;
+
+ dropit:
+	*hotdrop = 1;
+	return 0;
 }
 
 static int
@@ -48,15 +59,11 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
 	const struct ipt_tcpmss_match_info *info = matchinfo;
-	const struct tcphdr *tcph = (void *)skb->nh.iph + skb->nh.iph->ihl*4;
 
-	return mssoption_match(info->mss_min, info->mss_max, tcph,
-			       skb->len - skb->nh.iph->ihl*4,
+	return mssoption_match(info->mss_min, info->mss_max, skb,
 			       info->invert, hotdrop);
 }
 
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_tos.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_tos.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_tos.c	2003-05-04 16:53:42.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_tos.c	2003-05-23 04:36:23.000000000 -0700
@@ -11,14 +11,11 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
 	const struct ipt_tos_info *info = matchinfo;
-	const struct iphdr *iph = skb->nh.iph;
 
-	return (iph->tos == info->tos) ^ info->invert;
+	return (skb->nh.iph->tos == info->tos) ^ info->invert;
 }
 
 static int
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_ttl.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_ttl.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_ttl.c	2003-05-04 16:53:57.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_ttl.c	2003-05-23 04:36:23.000000000 -0700
@@ -19,24 +19,22 @@
 
 static int match(const struct sk_buff *skb, const struct net_device *in,
 		 const struct net_device *out, const void *matchinfo,
-		 int offset, const void *hdr, u_int16_t datalen,
-		 int *hotdrop)
+		 int offset, int *hotdrop)
 {
 	const struct ipt_ttl_info *info = matchinfo;
-	const struct iphdr *iph = skb->nh.iph;
 
 	switch (info->mode) {
 		case IPT_TTL_EQ:
-			return (iph->ttl == info->ttl);
+			return (skb->nh.iph->ttl == info->ttl);
 			break;
 		case IPT_TTL_NE:
-			return (!(iph->ttl == info->ttl));
+			return (!(skb->nh.iph->ttl == info->ttl));
 			break;
 		case IPT_TTL_LT:
-			return (iph->ttl < info->ttl);
+			return (skb->nh.iph->ttl < info->ttl);
 			break;
 		case IPT_TTL_GT:
-			return (iph->ttl > info->ttl);
+			return (skb->nh.iph->ttl > info->ttl);
 			break;
 		default:
 			printk(KERN_WARNING "ipt_ttl: unknown mode %d\n", 
diff -urN linux-2.5.69-bk15/net/ipv4/netfilter/ipt_unclean.c linux-2.5.69-bk16/net/ipv4/netfilter/ipt_unclean.c
--- linux-2.5.69-bk15/net/ipv4/netfilter/ipt_unclean.c	2003-05-04 16:53:32.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/netfilter/ipt_unclean.c	2003-05-23 04:36:23.000000000 -0700
@@ -31,16 +31,17 @@
 };
 
 static int
-check_ip(struct iphdr *iph, size_t length, int embedded);
+check_ip(const struct sk_buff *skb, unsigned int offset);
 
 /* ICMP-specific checks. */
 static int
-check_icmp(const struct icmphdr *icmph,
-	   u_int16_t datalen,
+check_icmp(const struct sk_buff *skb,
 	   unsigned int offset,
+	   unsigned int fragoff,
 	   int more_frags,
 	   int embedded)
 {
+	struct icmphdr icmph;
 	static struct icmp_info info[]
 		= { [ICMP_ECHOREPLY]
 		    = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
@@ -76,92 +77,95 @@
 		    = { 12, 12, ICMP_NOT_ERROR, 0, 0 } };
 
 	/* Can't do anything if it's a fragment. */
-	if (offset)
+	if (fragoff)
 		return 1;
 
-	/* Must cover type and code. */
-	if (datalen < 2) {
-		limpk("ICMP len=%u too short\n", datalen);
+	/* CHECK: Must have whole header.. */
+	if (skb_copy_bits(skb, offset, &icmph, sizeof(icmph)) < 0) {
+		limpk("ICMP len=%u too short\n", skb->len - offset);
 		return 0;
 	}
 
-	/* If not embedded. */
+	/* If not embedded in an ICMP error already. */
 	if (!embedded) {
-		/* Bad checksum?  Don't print, just ignore. */
-		if (!more_frags
-		    && ip_compute_csum((unsigned char *) icmph, datalen) != 0)
-			return 0;
-
 		/* CHECK: Truncated ICMP (even if first fragment). */
-		if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
-		    && info[icmph->type].min_len != 0
-		    && datalen < info[icmph->type].min_len) {
+		if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
+		    && info[icmph.type].min_len != 0
+		    && skb->len - offset < info[icmph.type].min_len) {
 			limpk("ICMP type %u len %u too short\n",
-			      icmph->type, datalen);
+			      icmph.type, skb->len - offset);
 			return 0;
 		}
 
 		/* CHECK: Check within known error ICMPs. */
-		if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
-		    && info[icmph->type].err == ICMP_IS_ERROR) {
+		if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
+		    && info[icmph.type].err == ICMP_IS_ERROR) {
+			/* Max IP header size = 60 */
+			char inner[60 + 8];
+			struct iphdr *inner_ip = (struct iphdr *)inner;
+
 			/* CHECK: Embedded packet must be at least
 			   length of iph + 8 bytes. */
-			struct iphdr *inner = (void *)icmph + 8;
-
-			/* datalen > 8 since all ICMP_IS_ERROR types
-                           have min length > 8 */
-			if (datalen - 8 < sizeof(struct iphdr)) {
+			if (skb_copy_bits(skb, offset + sizeof(icmph),
+					  inner, sizeof(struct iphdr)+8) < 0) {
 				limpk("ICMP error internal way too short\n");
 				return 0;
 			}
-			if (datalen - 8 < inner->ihl*4 + 8) {
+
+			/* iphhdr may actually be longer: still need 8
+                           actual protocol bytes. */
+			if (offset + sizeof(icmph) + inner_ip->ihl*4 + 8
+			    > skb->len) {
 				limpk("ICMP error internal too short\n");
 				return 0;
 			}
-			if (!check_ip(inner, datalen - 8, 1))
+			if (!check_ip(skb, offset + sizeof(icmph)))
 				return 0;
 		}
 	} else {
 		/* CHECK: Can't embed ICMP unless known non-error. */
-		if (icmph->type >= sizeof(info)/sizeof(struct icmp_info)
-		    || info[icmph->type].err != ICMP_NOT_ERROR) {
+		if (icmph.type >= sizeof(info)/sizeof(struct icmp_info)
+		    || info[icmph.type].err != ICMP_NOT_ERROR) {
 			limpk("ICMP type %u not embeddable\n",
-			      icmph->type);
+			      icmph.type);
 			return 0;
 		}
 	}
 
 	/* CHECK: Invalid ICMP codes. */
-	if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
-	    && (icmph->code < info[icmph->type].min_code
-		|| icmph->code > info[icmph->type].max_code)) {
+	if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
+	    && (icmph.code < info[icmph.type].min_code
+		|| icmph.code > info[icmph.type].max_code)) {
 		limpk("ICMP type=%u code=%u\n",
-		      icmph->type, icmph->code);
+		      icmph.type, icmph.code);
 		return 0;
 	}
 
 	/* CHECK: Above maximum length. */
-	if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
-	    && info[icmph->type].max_len != 0
-	    && datalen > info[icmph->type].max_len) {
+	if (icmph.type < sizeof(info)/sizeof(struct icmp_info)
+	    && info[icmph.type].max_len != 0
+	    && skb->len - offset > info[icmph.type].max_len) {
 		limpk("ICMP type=%u too long: %u bytes\n",
-		      icmph->type, datalen);
+		      icmph.type, skb->len - offset);
 		return 0;
 	}
 
-	switch (icmph->type) {
+	switch (icmph.type) {
 	case ICMP_PARAMETERPROB: {
 		/* CHECK: Problem param must be within error packet's
 		 * IP header. */
-		struct iphdr *iph = (void *)icmph + 8;
-		u_int32_t arg = ntohl(icmph->un.gateway);
+		u_int32_t arg = ntohl(icmph.un.gateway);
 
-		if (icmph->code == 0) {
+		if (icmph.code == 0) {
+			/* We've already made sure it's long enough. */
+			struct iphdr iph;
+			skb_copy_bits(skb, offset + sizeof(icmph), &iph,
+				      sizeof(iph));
 			/* Code 0 means that upper 8 bits is pointer
                            to problem. */
-			if ((arg >> 24) >= iph->ihl*4) {
+			if ((arg >> 24) >= iph.ihl*4) {
 				limpk("ICMP PARAMETERPROB ptr = %u\n",
-				      ntohl(icmph->un.gateway) >> 24);
+				      ntohl(icmph.un.gateway) >> 24);
 				return 0;
 			}
 			arg &= 0x00FFFFFF;
@@ -179,9 +183,9 @@
 	case ICMP_TIME_EXCEEDED:
 	case ICMP_SOURCE_QUENCH:
 		/* CHECK: Unused must be zero. */
-		if (icmph->un.gateway != 0) {
+		if (icmph.un.gateway != 0) {
 			limpk("ICMP type=%u unused = %u\n",
-			      icmph->type, ntohl(icmph->un.gateway));
+			      icmph.type, ntohl(icmph.un.gateway));
 			return 0;
 		}
 		break;
@@ -192,32 +196,26 @@
 
 /* UDP-specific checks. */
 static int
-check_udp(const struct iphdr *iph,
-	  const struct udphdr *udph,
-	  u_int16_t datalen,
+check_udp(const struct sk_buff *skb,
 	  unsigned int offset,
+	  unsigned int fragoff,
 	  int more_frags,
 	  int embedded)
 {
+	struct udphdr udph;
+
 	/* Can't do anything if it's a fragment. */
-	if (offset)
+	if (fragoff)
 		return 1;
 
 	/* CHECK: Must cover UDP header. */
-	if (datalen < sizeof(struct udphdr)) {
-		limpk("UDP len=%u too short\n", datalen);
+	if (skb_copy_bits(skb, offset, &udph, sizeof(udph)) < 0) {
+		limpk("UDP len=%u too short\n", skb->len - offset);
 		return 0;
 	}
 
-	/* Bad checksum?  Don't print, just say it's unclean. */
-	/* FIXME: SRC ROUTE packets won't match checksum --RR */
-	if (!more_frags && !embedded && udph->check
-	    && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP,
-				 csum_partial((char *)udph, datalen, 0)) != 0)
-		return 0;
-
 	/* CHECK: Destination port can't be zero. */
-	if (!udph->dest) {
+	if (!udph.dest) {
 		limpk("UDP zero destination port\n");
 		return 0;
 	}
@@ -225,24 +223,24 @@
 	if (!more_frags) {
 		if (!embedded) {
 			/* CHECK: UDP length must match. */
-			if (ntohs(udph->len) != datalen) {
+			if (ntohs(udph.len) != skb->len - offset) {
 				limpk("UDP len too short %u vs %u\n",
-				      ntohs(udph->len), datalen);
+				      ntohs(udph.len), skb->len - offset);
 				return 0;
 			}
 		} else {
 			/* CHECK: UDP length be >= this truncated pkt. */
-			if (ntohs(udph->len) < datalen) {
+			if (ntohs(udph.len) < skb->len - offset) {
 				limpk("UDP len too long %u vs %u\n",
-				      ntohs(udph->len), datalen);
+				      ntohs(udph.len), skb->len - offset);
 				return 0;
 			}
 		}
 	} else {
 		/* CHECK: UDP length must be > this frag's length. */
-		if (ntohs(udph->len) <= datalen) {
+		if (ntohs(udph.len) <= skb->len - offset) {
 			limpk("UDP fragment len too short %u vs %u\n",
-			      ntohs(udph->len), datalen);
+			      ntohs(udph.len), skb->len - offset);
 			return 0;
 		}
 	}
@@ -250,104 +248,104 @@
 	return 1;
 }
 
-#define	TH_FIN	0x01
-#define	TH_SYN	0x02
-#define	TH_RST	0x04
-#define	TH_PUSH	0x08
-#define	TH_ACK	0x10
-#define	TH_URG	0x20
-#define	TH_ECE	0x40
-#define	TH_CWR	0x80
-
 /* TCP-specific checks. */
 static int
-check_tcp(const struct iphdr *iph,
-	  const struct tcphdr *tcph,
-	  u_int16_t datalen,
+check_tcp(const struct sk_buff *skb,
 	  unsigned int offset,
+	  unsigned int fragoff,
 	  int more_frags,
 	  int embedded)
 {
-	u_int8_t *opt = (u_int8_t *)tcph;
-	u_int8_t *endhdr = (u_int8_t *)tcph + tcph->doff * 4;
-	u_int8_t tcpflags;
+	struct tcphdr tcph; 
+	unsigned char opt[15 * 4 - sizeof(struct tcphdr)];
+	u32 tcpflags;
 	int end_of_options = 0;
-	size_t i;
+	unsigned int i, optlen;
 
 	/* CHECK: Can't have offset=1: used to override TCP syn-checks. */
 	/* In fact, this is caught below (offset < 516). */
 
 	/* Can't do anything if it's a fragment. */
-	if (offset)
+	if (fragoff)
 		return 1;
 
 	/* CHECK: Smaller than minimal TCP hdr. */
-	if (datalen < sizeof(struct tcphdr)) {
+	if (skb_copy_bits(skb, offset, &tcph, sizeof(tcph)) < 0) {
+		u16 ports[2];
+
 		if (!embedded) {
-			limpk("Packet length %u < TCP header.\n", datalen);
+			limpk("Packet length %u < TCP header.\n",
+			      skb->len - offset);
 			return 0;
 		}
+
 		/* Must have ports available (datalen >= 8), from
                    check_icmp which set embedded = 1 */
 		/* CHECK: TCP ports inside ICMP error */
-		if (!tcph->source || !tcph->dest) {
+		skb_copy_bits(skb, offset, ports, sizeof(ports));
+		if (!ports[0] || !ports[1]) {
 			limpk("Zero TCP ports %u/%u.\n",
-			      htons(tcph->source), htons(tcph->dest));
+			      htons(ports[0]), htons(ports[1]));
 			return 0;
 		}
 		return 1;
 	}
 
-	/* CHECK: Smaller than actual TCP hdr. */
-	if (datalen < tcph->doff * 4) {
+	/* CHECK: TCP header claims tiny size. */
+	if (tcph.doff * 4 < sizeof(tcph)) {
+		limpk("TCP header claims tiny size %u\n", tcph.doff * 4);
+		return 0;
+	}
+
+	/* CHECK: Packet smaller than actual TCP hdr. */
+	optlen = tcph.doff*4 - sizeof(tcph);
+	if (skb_copy_bits(skb, offset + sizeof(tcph), opt, optlen) < 0) {
 		if (!embedded) {
 			limpk("Packet length %u < actual TCP header.\n",
-			      datalen);
+			      skb->len - offset);
 			return 0;
 		} else
 			return 1;
 	}
 
-	/* Bad checksum?  Don't print, just say it's unclean. */
-	/* FIXME: SRC ROUTE packets won't match checksum --RR */
-	if (!more_frags && !embedded
-	    && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_TCP,
-				 csum_partial((char *)tcph, datalen, 0)) != 0)
-		return 0;
-
 	/* CHECK: TCP ports non-zero */
-	if (!tcph->source || !tcph->dest) {
+	if (!tcph.source || !tcph.dest) {
 		limpk("Zero TCP ports %u/%u.\n",
-		      htons(tcph->source), htons(tcph->dest));
+		      htons(tcph.source), htons(tcph.dest));
 		return 0;
 	}
 
+	tcpflags = tcp_flag_word(&tcph);
+
 	/* CHECK: TCP reserved bits zero. */
-	if(tcp_flag_word(tcph) & TCP_RESERVED_BITS) {
+	if (tcpflags & TCP_RESERVED_BITS) {
 		limpk("TCP reserved bits not zero\n");
 		return 0;
 	}
 
+	tcpflags &= ~(TCP_DATA_OFFSET | TCP_FLAG_CWR | TCP_FLAG_ECE
+		      | __constant_htonl(0x0000FFFF));
+
 	/* CHECK: TCP flags. */
-	tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
-	if (tcpflags != TH_SYN
-	    && tcpflags != (TH_SYN|TH_ACK)
-		&& tcpflags != TH_RST
-	    && tcpflags != (TH_RST|TH_ACK)
-	    && tcpflags != (TH_RST|TH_ACK|TH_PUSH)
-	    && tcpflags != (TH_FIN|TH_ACK)
-	    && tcpflags != TH_ACK
-	    && tcpflags != (TH_ACK|TH_PUSH)
-	    && tcpflags != (TH_ACK|TH_URG)
-	    && tcpflags != (TH_ACK|TH_URG|TH_PUSH)
-	    && tcpflags != (TH_FIN|TH_ACK|TH_PUSH)
-	    && tcpflags != (TH_FIN|TH_ACK|TH_URG)
-	    && tcpflags != (TH_FIN|TH_ACK|TH_URG|TH_PUSH)) {
-		limpk("TCP flags bad: %u\n", tcpflags);
+	if (tcpflags != TCP_FLAG_SYN
+	    && tcpflags != (TCP_FLAG_SYN|TCP_FLAG_ACK)
+	    && tcpflags != TCP_FLAG_RST
+	    && tcpflags != (TCP_FLAG_RST|TCP_FLAG_ACK)
+	    && tcpflags != (TCP_FLAG_RST|TCP_FLAG_ACK|TCP_FLAG_PSH)
+	    && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK)
+	    && tcpflags != TCP_FLAG_ACK
+	    && tcpflags != (TCP_FLAG_ACK|TCP_FLAG_PSH)
+	    && tcpflags != (TCP_FLAG_ACK|TCP_FLAG_URG)
+	    && tcpflags != (TCP_FLAG_ACK|TCP_FLAG_URG|TCP_FLAG_PSH)
+	    && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_PSH)
+	    && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_URG)
+	    && tcpflags != (TCP_FLAG_FIN|TCP_FLAG_ACK|TCP_FLAG_URG
+			    |TCP_FLAG_PSH)) {
+		limpk("TCP flags bad: 0x%04X\n", ntohl(tcpflags) >> 16);
 		return 0;
 	}
 
-	for (i = sizeof(struct tcphdr); i < tcph->doff * 4; ) {
+	for (i = 0; i < optlen; ) {
 		switch (opt[i]) {
 		case 0:
 			end_of_options = 1;
@@ -364,7 +362,7 @@
 				return 0;
 			}
 			/* CHECK: options at tail. */
-			else if (i+1 >= tcph->doff * 4) {
+			else if (i+1 >= optlen) {
 				limpk("TCP option %u at tail\n",
 				      opt[i]);
 				return 0;
@@ -376,8 +374,8 @@
 				return 0;
 			}
 			/* CHECK: oversize options. */
-			else if (&opt[i] + opt[i+1] > endhdr) {
-				limpk("TCP option %u at %Zu too long\n",
+			else if (i + opt[i+1] > optlen) {
+				limpk("TCP option %u at %u too long\n",
 				      (unsigned int) opt[i], i);
 				return 0;
 			}
@@ -392,34 +390,44 @@
 /* Returns 1 if ok */
 /* Standard IP checks. */
 static int
-check_ip(struct iphdr *iph, size_t length, int embedded)
+check_ip(const struct sk_buff *skb, unsigned int offset)
 {
-	u_int8_t *opt = (u_int8_t *)iph;
-	u_int8_t *endhdr = (u_int8_t *)iph + iph->ihl * 4;
 	int end_of_options = 0;
-	void *protoh;
-	size_t datalen;
+	unsigned int datalen, optlen;
 	unsigned int i;
-	unsigned int offset;
+	unsigned int fragoff;
+	struct iphdr iph;
+	unsigned char opt[15 * 4 - sizeof(struct iphdr)];
+	int embedded = offset;
 
 	/* Should only happen for local outgoing raw-socket packets. */
 	/* CHECK: length >= ip header. */
-	if (length < sizeof(struct iphdr) || length < iph->ihl * 4) {
-		limpk("Packet length %Zu < IP header.\n", length);
+	if (skb_copy_bits(skb, offset, &iph, sizeof(iph)) < 0) {
+		limpk("Packet length %u < IP header.\n", skb->len - offset);
+		return 0;
+	}
+	if (iph.ihl * 4 < sizeof(iph)) {
+		limpk("IP len %u < minimum IP header.\n", iph.ihl*4);
+		return 0;
+	}
+
+	optlen = iph.ihl * 4 - sizeof(iph);
+	if (skb_copy_bits(skb, offset+sizeof(struct iphdr), opt, optlen)<0) {
+		limpk("Packet length %u < IP header %u.\n",
+		      skb->len - offset, iph.ihl * 4);
 		return 0;
 	}
 
-	offset = ntohs(iph->frag_off) & IP_OFFSET;
-	protoh = (void *)iph + iph->ihl * 4;
-	datalen = length - iph->ihl * 4;
+	fragoff = (ntohs(iph.frag_off) & IP_OFFSET);
+	datalen = skb->len - (offset + sizeof(struct iphdr) + optlen);
 
 	/* CHECK: Embedded fragment. */
-	if (embedded && offset) {
+	if (offset && fragoff) {
 		limpk("Embedded fragment.\n");
 		return 0;
 	}
 
-	for (i = sizeof(struct iphdr); i < iph->ihl * 4; ) {
+	for (i = 0; i < optlen; ) {
 		switch (opt[i]) {
 		case 0:
 			end_of_options = 1;
@@ -436,7 +444,7 @@
 				return 0;
 			}
 			/* CHECK: options at tail. */
-			else if (i+1 >= iph->ihl * 4) {
+			else if (i+1 >= optlen) {
 				limpk("IP option %u at tail\n",
 				      opt[i]);
 				return 0;
@@ -448,7 +456,7 @@
 				return 0;
 			}
 			/* CHECK: oversize options. */
-			else if (&opt[i] + opt[i+1] > endhdr) {
+			else if (i + opt[i+1] > optlen) {
 				limpk("IP option %u at %u too long\n",
 				      opt[i], i);
 				return 0;
@@ -461,30 +469,30 @@
 	/* Fragment checks. */
 
 	/* CHECK: More fragments, but doesn't fill 8-byte boundary. */
-	if ((ntohs(iph->frag_off) & IP_MF)
-	    && (ntohs(iph->tot_len) % 8) != 0) {
-		limpk("Truncated fragment %u long.\n", ntohs(iph->tot_len));
+	if ((ntohs(iph.frag_off) & IP_MF)
+	    && (ntohs(iph.tot_len) % 8) != 0) {
+		limpk("Truncated fragment %u long.\n", ntohs(iph.tot_len));
 		return 0;
 	}
 
 	/* CHECK: Oversize fragment a-la Ping of Death. */
-	if (offset * 8 + datalen > 65535) {
-		limpk("Oversize fragment to %u.\n", offset * 8);
+	if (fragoff * 8 + datalen > 65535) {
+		limpk("Oversize fragment to %u.\n", fragoff * 8);
 		return 0;
 	}
 
-	/* CHECK: DF set and offset or MF set. */
-	if ((ntohs(iph->frag_off) & IP_DF)
-	    && (offset || (ntohs(iph->frag_off) & IP_MF))) {
+	/* CHECK: DF set and fragoff or MF set. */
+	if ((ntohs(iph.frag_off) & IP_DF)
+	    && (fragoff || (ntohs(iph.frag_off) & IP_MF))) {
 		limpk("DF set and offset=%u, MF=%u.\n",
-		      offset, ntohs(iph->frag_off) & IP_MF);
+		      fragoff, ntohs(iph.frag_off) & IP_MF);
 		return 0;
 	}
 
 	/* CHECK: Zero-sized fragments. */
-	if ((offset || (ntohs(iph->frag_off) & IP_MF))
+	if ((fragoff || (ntohs(iph.frag_off) & IP_MF))
 	    && datalen == 0) {
-		limpk("Zero size fragment offset=%u\n", offset);
+		limpk("Zero size fragment offset=%u\n", fragoff);
 		return 0;
 	}
 
@@ -500,52 +508,54 @@
 	   here. */
 #define MIN_LIKELY_MTU 128
 	/* CHECK: Min size of first frag = 128. */
-	if ((ntohs(iph->frag_off) & IP_MF)
-	    && offset == 0
-	    && ntohs(iph->tot_len) < MIN_LIKELY_MTU) {
-		limpk("First fragment size %u < %u\n", ntohs(iph->tot_len),
+	if ((ntohs(iph.frag_off) & IP_MF)
+	    && fragoff == 0
+	    && ntohs(iph.tot_len) < MIN_LIKELY_MTU) {
+		limpk("First fragment size %u < %u\n", ntohs(iph.tot_len),
 		      MIN_LIKELY_MTU);
 		return 0;
 	}
 
 	/* CHECK: Min offset of frag = 128 - IP hdr len. */
-	if (offset && offset * 8 < MIN_LIKELY_MTU - iph->ihl * 4) {
-		limpk("Fragment starts at %u < %u\n", offset * 8,
-		      MIN_LIKELY_MTU - iph->ihl * 4);
+	if (fragoff && fragoff * 8 < MIN_LIKELY_MTU - iph.ihl * 4) {
+		limpk("Fragment starts at %u < %u\n", fragoff * 8,
+		      MIN_LIKELY_MTU - iph.ihl * 4);
 		return 0;
 	}
 
 	/* CHECK: Protocol specification non-zero. */
-	if (iph->protocol == 0) {
+	if (iph.protocol == 0) {
 		limpk("Zero protocol\n");
 		return 0;
 	}
 
+	/* FIXME: This is already checked for in "Oversize fragment"
+           above --RR */
 	/* CHECK: Do not use what is unused.
 	 * First bit of fragmentation flags should be unused.
 	 * May be used by OS fingerprinting tools.
 	 * 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv
 	 */
-	if (ntohs(iph->frag_off)>>15) {
+	if (ntohs(iph.frag_off)>>15) {
 		limpk("IP unused bit set\n");
 		return 0;
 	}
 
 	/* Per-protocol checks. */
-	switch (iph->protocol) {
+	switch (iph.protocol) {
 	case IPPROTO_ICMP:
-		return check_icmp(protoh, datalen, offset,
-				  (ntohs(iph->frag_off) & IP_MF),
+		return check_icmp(skb, offset + iph.ihl*4, fragoff,
+				  (ntohs(iph.frag_off) & IP_MF),
 				  embedded);
 
 	case IPPROTO_UDP:
-		return check_udp(iph, protoh, datalen, offset,
-				 (ntohs(iph->frag_off) & IP_MF),
+		return check_udp(skb, offset + iph.ihl*4, fragoff,
+				 (ntohs(iph.frag_off) & IP_MF),
 				 embedded);
 
 	case IPPROTO_TCP:
-		return check_tcp(iph, protoh, datalen, offset,
-				 (ntohs(iph->frag_off) & IP_MF),
+		return check_tcp(skb, offset + iph.ihl*4, fragoff,
+				 (ntohs(iph.frag_off) & IP_MF),
 				 embedded);
 	default:
 		/* Ignorance is bliss. */
@@ -559,11 +569,9 @@
       const struct net_device *out,
       const void *matchinfo,
       int offset,
-      const void *hdr,
-      u_int16_t datalen,
       int *hotdrop)
 {
-	return !check_ip(skb->nh.iph, skb->len, 0);
+	return !check_ip(skb, 0);
 }
 
 /* Called when user tries to insert an entry of this type. */
diff -urN linux-2.5.69-bk15/net/ipv4/proc.c linux-2.5.69-bk16/net/ipv4/proc.c
--- linux-2.5.69-bk15/net/ipv4/proc.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/proc.c	2003-05-23 04:36:23.000000000 -0700
@@ -265,11 +265,3 @@
 	goto out;
 }
 
-int ip_seq_release(struct inode *inode, struct file *file)
-{
-	struct seq_file *seq = (struct seq_file *)file->private_data;
-
-	kfree(seq->private);
-	seq->private = NULL;
-	return seq_release(inode, file);
-}
diff -urN linux-2.5.69-bk15/net/ipv4/route.c linux-2.5.69-bk16/net/ipv4/route.c
--- linux-2.5.69-bk15/net/ipv4/route.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/route.c	2003-05-23 04:36:23.000000000 -0700
@@ -386,7 +386,7 @@
 	.open	 = rt_cache_seq_open,
 	.read	 = seq_read,
 	.llseek	 = seq_lseek,
-	.release = ip_seq_release,
+	.release = seq_release_private,
 };
 
 int __init rt_cache_proc_init(void)
diff -urN linux-2.5.69-bk15/net/ipv4/tcp_ipv4.c linux-2.5.69-bk16/net/ipv4/tcp_ipv4.c
--- linux-2.5.69-bk15/net/ipv4/tcp_ipv4.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/tcp_ipv4.c	2003-05-23 04:36:23.000000000 -0700
@@ -2568,7 +2568,7 @@
 	.open		=	tcp_seq_open,
 	.read		=	seq_read,
 	.llseek		=	seq_lseek,
-	.release	=	ip_seq_release,
+	.release	=	seq_release_private,
 };
 
 int __init tcp_proc_init(void)
diff -urN linux-2.5.69-bk15/net/ipv4/udp.c linux-2.5.69-bk16/net/ipv4/udp.c
--- linux-2.5.69-bk15/net/ipv4/udp.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/udp.c	2003-05-23 04:36:23.000000000 -0700
@@ -1391,8 +1391,11 @@
 
 	sk = v;
 	sk = sk->next;
-	if (sk) 
-		goto out;
+
+	for (; sk; sk = sk->next) {
+		if (sk->family == AF_INET)
+			goto out;
+	}
 
 	state = seq->private;
 	if (++state->bucket >= UDP_HTABLE_SIZE) 
@@ -1479,7 +1482,7 @@
 	.open           = udp_seq_open,
 	.read           = seq_read,
 	.llseek         = seq_lseek,
-	.release	= ip_seq_release,
+	.release	= seq_release_private,
 };
 
 /* ------------------------------------------------------------------------ */
diff -urN linux-2.5.69-bk15/net/ipv4/xfrm4_tunnel.c linux-2.5.69-bk16/net/ipv4/xfrm4_tunnel.c
--- linux-2.5.69-bk15/net/ipv4/xfrm4_tunnel.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv4/xfrm4_tunnel.c	2003-05-23 04:36:23.000000000 -0700
@@ -229,7 +229,7 @@
 
 static int __init ipip_init(void)
 {
-	SET_MODULE_OWNER(&ipip_type);
+	ipip_type.owner = THIS_MODULE;
 	if (xfrm_register_type(&ipip_type, AF_INET) < 0) {
 		printk(KERN_INFO "ipip init: can't add xfrm type\n");
 		return -EAGAIN;
diff -urN linux-2.5.69-bk15/net/ipv6/af_inet6.c linux-2.5.69-bk16/net/ipv6/af_inet6.c
--- linux-2.5.69-bk15/net/ipv6/af_inet6.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/af_inet6.c	2003-05-23 04:36:23.000000000 -0700
@@ -77,11 +77,13 @@
 extern int raw6_proc_init(void);
 extern int raw6_proc_exit(void);
 
-extern int anycast6_get_info(char *, char **, off_t, int);
 extern int tcp6_get_info(char *, char **, off_t, int);
 extern int udp6_get_info(char *, char **, off_t, int);
-extern int afinet6_get_info(char *, char **, off_t, int);
-extern int afinet6_get_snmp(char *, char **, off_t, int);
+
+extern int ipv6_misc_proc_init(void);
+extern int ipv6_misc_proc_exit(void);
+
+extern int anycast6_get_info(char *, char **, off_t, int);
 #endif
 
 #ifdef CONFIG_SYSCTL
@@ -816,9 +818,7 @@
 
 #ifdef CONFIG_PROC_FS
 proc_anycast6_fail:
-	proc_net_remove("snmp6");
-	proc_net_remove("dev_snmp6");
-	proc_net_remove("sockstat6");
+	ipv6_misc_proc_exit();
 proc_misc6_fail:
 	proc_net_remove("udp6");
 proc_udp6_fail:
@@ -852,9 +852,7 @@
 	raw6_proc_exit();
 	proc_net_remove("tcp6");
 	proc_net_remove("udp6");
-	proc_net_remove("sockstat6");
-	proc_net_remove("dev_snmp6");
-	proc_net_remove("snmp6");
+	ipv6_misc_proc_exit();
 	proc_net_remove("anycast6");
 #endif
 	/* Cleanup code parts. */
diff -urN linux-2.5.69-bk15/net/ipv6/anycast.c linux-2.5.69-bk16/net/ipv6/anycast.c
--- linux-2.5.69-bk15/net/ipv6/anycast.c	2003-05-04 16:52:49.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/anycast.c	2003-05-23 04:36:23.000000000 -0700
@@ -127,8 +127,8 @@
 			dev_hold(dev);
 			dst_release(&rt->u.dst);
 		} else if (ishost) {
-			sock_kfree_s(sk, pac, sizeof(*pac));
-			return -EADDRNOTAVAIL;
+			err = -EADDRNOTAVAIL;
+			goto out_free_pac;
 		} else {
 			/* router, no matching interface: just pick one */
 
@@ -138,18 +138,17 @@
 		dev = dev_get_by_index(ifindex);
 
 	if (dev == NULL) {
-		sock_kfree_s(sk, pac, sizeof(*pac));
-		return -ENODEV;
+		err = -ENODEV;
+		goto out_free_pac;
 	}
 
 	idev = in6_dev_get(dev);
 	if (!idev) {
-		sock_kfree_s(sk, pac, sizeof(*pac));
-		dev_put(dev);
 		if (ifindex)
-			return -ENODEV;
+			err = -ENODEV;
 		else
-			return -EADDRNOTAVAIL;
+			err = -EADDRNOTAVAIL;
+		goto out_dev_put;
 	}
 	/* reset ishost, now that we have a specific device */
 	ishost = !idev->cnf.forwarding;
@@ -170,21 +169,17 @@
 			err = -EADDRNOTAVAIL;
 		else if (!capable(CAP_NET_ADMIN))
 			err = -EPERM;
-		if (err) {
-			sock_kfree_s(sk, pac, sizeof(*pac));
-			dev_put(dev);
-			return err;
-		}
+		if (err)
+			goto out_dev_put;
 	} else if (!(ipv6_addr_type(addr) & IPV6_ADDR_ANYCAST) &&
-		   !capable(CAP_NET_ADMIN))
-		return -EPERM;
+		   !capable(CAP_NET_ADMIN)) {
+		err = -EPERM;
+		goto out_dev_put;
+	}
 
 	err = ipv6_dev_ac_inc(dev, addr);
-	if (err) {
-		sock_kfree_s(sk, pac, sizeof(*pac));
-		dev_put(dev);
-		return err;
-	}
+	if (err)
+		goto out_dev_put;
 
 	write_lock_bh(&ipv6_sk_ac_lock);
 	pac->acl_next = np->ipv6_ac_list;
@@ -194,6 +189,12 @@
 	dev_put(dev);
 
 	return 0;
+
+out_dev_put:
+	dev_put(dev);
+out_free_pac:
+	sock_kfree_s(sk, pac, sizeof(*pac));
+	return err;
 }
 
 /*
diff -urN linux-2.5.69-bk15/net/ipv6/datagram.c linux-2.5.69-bk16/net/ipv6/datagram.c
--- linux-2.5.69-bk15/net/ipv6/datagram.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/datagram.c	2003-05-23 04:36:23.000000000 -0700
@@ -80,7 +80,7 @@
 
 	iph = (struct ipv6hdr*)skb_put(skb, sizeof(struct ipv6hdr));
 	skb->nh.ipv6h = iph;
-	ipv6_addr_copy(&iph->daddr, fl->fl6_dst);
+	ipv6_addr_copy(&iph->daddr, &fl->fl6_dst);
 
 	serr = SKB_EXT_ERR(skb);
 	serr->ee.ee_errno = err;
@@ -297,7 +297,8 @@
 					goto exit_f;
 				}
 
-				fl->fl6_src = &src_info->ipi6_addr;
+				ipv6_addr_copy(&fl->fl6_src,
+					       &src_info->ipi6_addr);
 			}
 
 			break;
diff -urN linux-2.5.69-bk15/net/ipv6/icmp.c linux-2.5.69-bk16/net/ipv6/icmp.c
--- linux-2.5.69-bk15/net/ipv6/icmp.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/icmp.c	2003-05-23 04:36:23.000000000 -0700
@@ -223,9 +223,10 @@
 	if (skb_queue_len(&sk->write_queue) == 1) {
 		skb->csum = csum_partial((char *)icmp6h,
 					sizeof(struct icmp6hdr), skb->csum);
-		icmp6h->icmp6_cksum = csum_ipv6_magic(fl->fl6_src,
-					     fl->fl6_dst,
-					     len, fl->proto, skb->csum);
+		icmp6h->icmp6_cksum = csum_ipv6_magic(&fl->fl6_src,
+						      &fl->fl6_dst,
+						      len, fl->proto,
+						      skb->csum);
 	} else {
 		u32 tmp_csum = 0;
 
@@ -235,8 +236,8 @@
 
 		tmp_csum = csum_partial((char *)icmp6h,
 					sizeof(struct icmp6hdr), tmp_csum);
-		tmp_csum = csum_ipv6_magic(fl->fl6_src,
-					   fl->fl6_dst,
+		tmp_csum = csum_ipv6_magic(&fl->fl6_src,
+					   &fl->fl6_dst,
 					   len, fl->proto, tmp_csum);
 		icmp6h->icmp6_cksum = tmp_csum;
 	}
@@ -266,7 +267,7 @@
 	struct ipv6hdr *hdr = skb->nh.ipv6h;
 	struct sock *sk = icmpv6_socket->sk;
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct in6_addr *saddr = NULL, *tmp_saddr = NULL;
+	struct in6_addr *saddr = NULL;
 	struct dst_entry *dst;
 	struct icmp6hdr tmp_hdr;
 	struct flowi fl;
@@ -332,11 +333,12 @@
 		return;
 	}
 
+	memset(&fl, 0, sizeof(fl));
 	fl.proto = IPPROTO_ICMPV6;
-	fl.fl6_dst = &hdr->saddr;
-	fl.fl6_src = saddr;
+	ipv6_addr_copy(&fl.fl6_dst, &hdr->saddr);
+	if (saddr)
+		ipv6_addr_copy(&fl.fl6_src, saddr);
 	fl.oif = iif;
-	fl.fl6_flowlabel = 0;
 	fl.fl_icmp_type = type;
 	fl.fl_icmp_code = code;
 
@@ -350,14 +352,14 @@
 	tmp_hdr.icmp6_cksum = 0;
 	tmp_hdr.icmp6_pointer = htonl(info);
 
-	if (!fl.oif && ipv6_addr_is_multicast(fl.fl6_dst))
+	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
 		fl.oif = np->mcast_oif;
 
-	err = ip6_dst_lookup(sk, &dst, &fl, &tmp_saddr);
+	err = ip6_dst_lookup(sk, &dst, &fl);
 	if (err) goto out;
 
 	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(fl.fl6_dst))
+		if (ipv6_addr_is_multicast(&fl.fl6_dst))
 			hlimit = np->mcast_hops;
 		else
 			hlimit = np->hop_limit;
@@ -394,7 +396,6 @@
 	if (likely(idev != NULL))
 		in6_dev_put(idev);
 out:
-	if (tmp_saddr) kfree(tmp_saddr);
 	icmpv6_xmit_unlock();
 }
 
@@ -403,7 +404,7 @@
 	struct sock *sk = icmpv6_socket->sk;
 	struct inet6_dev *idev;
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct in6_addr *saddr = NULL, *tmp_saddr = NULL;
+	struct in6_addr *saddr = NULL;
 	struct icmp6hdr *icmph = (struct icmp6hdr *) skb->h.raw;
 	struct icmp6hdr tmp_hdr;
 	struct flowi fl;
@@ -420,25 +421,25 @@
 	memcpy(&tmp_hdr, icmph, sizeof(tmp_hdr));
 	tmp_hdr.icmp6_type = ICMPV6_ECHO_REPLY;
 
+	memset(&fl, 0, sizeof(fl));
 	fl.proto = IPPROTO_ICMPV6;
-	fl.fl6_dst = &skb->nh.ipv6h->saddr;
-	fl.fl6_src = saddr;
+	ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr);
+	if (saddr)
+		ipv6_addr_copy(&fl.fl6_src, saddr);
 	fl.oif = skb->dev->ifindex;
-	fl.fl6_flowlabel = 0;
 	fl.fl_icmp_type = ICMPV6_ECHO_REPLY;
-	fl.fl_icmp_code = 0;
 
 	icmpv6_xmit_lock();
 
-	if (!fl.oif && ipv6_addr_is_multicast(fl.nl_u.ip6_u.daddr))
+	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
 		fl.oif = np->mcast_oif;
 
-	err = ip6_dst_lookup(sk, &dst, &fl, &tmp_saddr);
+	err = ip6_dst_lookup(sk, &dst, &fl);
 
 	if (err) goto out;
 
 	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(fl.fl6_dst))
+		if (ipv6_addr_is_multicast(&fl.fl6_dst))
 			hlimit = np->mcast_hops;
 		else
 			hlimit = np->hop_limit;
@@ -464,7 +465,6 @@
 	if (likely(idev != NULL))
 		in6_dev_put(idev);
 out: 
-	if (tmp_saddr) kfree(tmp_saddr);
 	icmpv6_xmit_unlock();
 }
 
diff -urN linux-2.5.69-bk15/net/ipv6/ip6_output.c linux-2.5.69-bk16/net/ipv6/ip6_output.c
--- linux-2.5.69-bk15/net/ipv6/ip6_output.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/ip6_output.c	2003-05-23 04:36:23.000000000 -0700
@@ -152,15 +152,14 @@
 {
 	struct ipv6hdr *iph = skb->nh.ipv6h;
 	struct dst_entry *dst;
-	struct flowi fl;
-
-	fl.proto = iph->nexthdr;
-	fl.fl6_dst = &iph->daddr;
-	fl.fl6_src = &iph->saddr;
-	fl.oif = skb->sk ? skb->sk->bound_dev_if : 0;
-	fl.fl6_flowlabel = 0;
-	fl.fl_ip_dport = 0;
-	fl.fl_ip_sport = 0;
+	struct flowi fl = {
+		.oif = skb->sk ? skb->sk->bound_dev_if : 0,
+		.nl_u =
+		{ .ip6_u =
+		  { .daddr = iph->daddr,
+		    .saddr = iph->saddr, } },
+		.proto = iph->nexthdr,
+	};
 
 	dst = ip6_route_output(skb->sk, &fl);
 
@@ -200,7 +199,7 @@
 	     struct ipv6_txoptions *opt)
 {
 	struct ipv6_pinfo *np = sk ? inet6_sk(sk) : NULL;
-	struct in6_addr *first_hop = fl->fl6_dst;
+	struct in6_addr *first_hop = &fl->fl6_dst;
 	struct dst_entry *dst = skb->dst;
 	struct ipv6hdr *hdr;
 	u8  proto = fl->proto;
@@ -255,7 +254,7 @@
 	hdr->nexthdr = proto;
 	hdr->hop_limit = hlimit;
 
-	ipv6_addr_copy(&hdr->saddr, fl->fl6_src);
+	ipv6_addr_copy(&hdr->saddr, &fl->fl6_src);
 	ipv6_addr_copy(&hdr->daddr, first_hop);
 
 	mtu = dst_pmtu(dst);
@@ -320,8 +319,8 @@
 	hdr->hop_limit = hlimit;
 	hdr->nexthdr = fl->proto;
 
-	ipv6_addr_copy(&hdr->saddr, fl->fl6_src);
-	ipv6_addr_copy(&hdr->daddr, fl->fl6_dst);
+	ipv6_addr_copy(&hdr->saddr, &fl->fl6_src);
+	ipv6_addr_copy(&hdr->daddr, &fl->fl6_dst);
 	return hdr;
 }
 
@@ -526,19 +525,19 @@
 {
 	struct inet_opt *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
-	struct in6_addr *final_dst = NULL;
+	struct in6_addr final_dst_buf, *final_dst = NULL;
 	struct dst_entry *dst;
 	int err = 0;
 	unsigned int pktlength, jumbolen, mtu;
-	struct in6_addr saddr;
 
 	if (opt && opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-		final_dst = fl->fl6_dst;
-		fl->fl6_dst = rt0->addr;
+		ipv6_addr_copy(&final_dst_buf, &fl->fl6_dst);
+		final_dst = &final_dst_buf;
+		ipv6_addr_copy(&fl->fl6_dst, rt0->addr);
 	}
 
-	if (!fl->oif && ipv6_addr_is_multicast(fl->fl6_dst))
+	if (!fl->oif && ipv6_addr_is_multicast(&fl->fl6_dst))
 		fl->oif = np->mcast_oif;
 
 	dst = __sk_dst_check(sk, np->dst_cookie);
@@ -564,9 +563,9 @@
 			 */
 
 		if (((rt->rt6i_dst.plen != 128 ||
-		      ipv6_addr_cmp(fl->fl6_dst, &rt->rt6i_dst.addr))
+		      ipv6_addr_cmp(&fl->fl6_dst, &rt->rt6i_dst.addr))
 		     && (np->daddr_cache == NULL ||
-			 ipv6_addr_cmp(fl->fl6_dst, np->daddr_cache)))
+			 ipv6_addr_cmp(&fl->fl6_dst, np->daddr_cache)))
 		    || (fl->oif && fl->oif != dst->dev->ifindex)) {
 			dst = NULL;
 		} else
@@ -582,8 +581,8 @@
 		return -ENETUNREACH;
 	}
 
-	if (fl->fl6_src == NULL) {
-		err = ipv6_get_saddr(dst, fl->fl6_dst, &saddr);
+	if (ipv6_addr_any(&fl->fl6_src)) {
+		err = ipv6_get_saddr(dst, &fl->fl6_dst, &fl->fl6_src);
 
 		if (err) {
 #if IP6_DEBUG >= 2
@@ -592,7 +591,6 @@
 #endif
 			goto out;
 		}
-		fl->fl6_src = &saddr;
 	}
 	pktlength = length;
 
@@ -604,7 +602,7 @@
         }
 
 	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(fl->fl6_dst))
+		if (ipv6_addr_is_multicast(&fl->fl6_dst))
 			hlimit = np->mcast_hops;
 		else
 			hlimit = np->hop_limit;
@@ -715,7 +713,9 @@
 	 *	cleanup
 	 */
 out:
-	ip6_dst_store(sk, dst, fl->fl6_dst == &np->daddr ? &np->daddr : NULL);
+	ip6_dst_store(sk, dst,
+		      !ipv6_addr_cmp(&fl->fl6_dst, &np->daddr) ?
+		      &np->daddr : NULL);
 	if (err > 0)
 		err = np->recverr ? net_xmit_errno(err) : 0;
 	return err;
@@ -1135,7 +1135,7 @@
 	return err;
 }
 
-int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl, struct in6_addr **saddr)
+int ip6_dst_lookup(struct sock *sk, struct dst_entry **dst, struct flowi *fl)
 {
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	int err = 0;
@@ -1163,9 +1163,9 @@
 			 */
 
 		if (((rt->rt6i_dst.plen != 128 ||
-		      ipv6_addr_cmp(fl->fl6_dst, &rt->rt6i_dst.addr))
+		      ipv6_addr_cmp(&fl->fl6_dst, &rt->rt6i_dst.addr))
 		     && (np->daddr_cache == NULL ||
-			 ipv6_addr_cmp(fl->fl6_dst, np->daddr_cache)))
+			 ipv6_addr_cmp(&fl->fl6_dst, np->daddr_cache)))
 		    || (fl->oif && fl->oif != (*dst)->dev->ifindex)) {
 			*dst = NULL;
 		} else
@@ -1181,9 +1181,8 @@
 		return -ENETUNREACH;
 	}
 
-	if (fl->fl6_src == NULL) {
-		*saddr = kmalloc(sizeof(struct in6_addr), GFP_ATOMIC);
-		err = ipv6_get_saddr(*dst, fl->fl6_dst, *saddr);
+	if (ipv6_addr_any(&fl->fl6_src)) {
+		err = ipv6_get_saddr(*dst, &fl->fl6_dst, &fl->fl6_src);
 
 		if (err) {
 #if IP6_DEBUG >= 2
@@ -1192,7 +1191,6 @@
 #endif
 			return err;
 		}
-		fl->fl6_src = *saddr;
 	}
 
         if (*dst) {
@@ -1415,7 +1413,7 @@
 {
 	struct sk_buff *skb, *tmp_skb;
 	struct sk_buff **tail_skb;
-	struct in6_addr *final_dst = NULL;
+	struct in6_addr final_dst_buf, *final_dst = &final_dst_buf;
 	struct inet_opt *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct ipv6hdr *hdr;
@@ -1446,7 +1444,7 @@
 #endif
 	}
 
-	final_dst = fl->fl6_dst;
+	ipv6_addr_copy(final_dst, &fl->fl6_dst);
 	__skb_pull(skb, skb->h.raw - skb->nh.raw);
 	if (opt && opt->opt_flen)
 		ipv6_push_frag_opts(skb, opt, &proto);
@@ -1463,7 +1461,7 @@
 		hdr->payload_len = 0;
 	hdr->hop_limit = np->hop_limit;
 	hdr->nexthdr = proto;
-	ipv6_addr_copy(&hdr->saddr, fl->fl6_src);
+	ipv6_addr_copy(&hdr->saddr, &fl->fl6_src);
 	ipv6_addr_copy(&hdr->daddr, final_dst);
 
 	skb->dst = dst_clone(&rt->u.dst);
diff -urN linux-2.5.69-bk15/net/ipv6/ndisc.c linux-2.5.69-bk16/net/ipv6/ndisc.c
--- linux-2.5.69-bk15/net/ipv6/ndisc.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/ndisc.c	2003-05-23 04:36:23.000000000 -0700
@@ -405,8 +405,8 @@
 			    struct in6_addr *saddr, struct in6_addr *daddr)
 {
 	memset(fl, 0, sizeof(*fl));
-	fl->fl6_src		= saddr;
-	fl->fl6_dst	 	= daddr;
+	ipv6_addr_copy(&fl->fl6_src, saddr);
+	ipv6_addr_copy(&fl->fl6_dst, daddr);
 	fl->proto	 	= IPPROTO_ICMPV6;
 	fl->fl_icmp_type	= type;
 	fl->fl_icmp_code	= 0;
@@ -441,8 +441,10 @@
 		src_addr = solicited_addr;
 		in6_ifa_put(ifp);
 	} else {
-		if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, 0))
+		if (ipv6_dev_get_saddr(dev, daddr, &tmpaddr, 0)) {
+			dst_free(dst);
 			return;
+		}
 		src_addr = &tmpaddr;
 	}
 
@@ -450,11 +452,10 @@
 	ndisc_rt_init(rt, dev, neigh);	
 
 	dst = (struct dst_entry*)rt;
-	dst_clone(dst);
 
 	err = xfrm_lookup(&dst, &fl, NULL, 0);
 	if (err < 0) {
-		dst_release(dst);
+		dst_free(dst);
 		return;
 	}
 
@@ -470,6 +471,7 @@
 
 	if (skb == NULL) {
 		ND_PRINTK1("send_na: alloc skb failed\n");
+		dst_free(dst);
 		return;
 	}
 
diff -urN linux-2.5.69-bk15/net/ipv6/proc.c linux-2.5.69-bk16/net/ipv6/proc.c
--- linux-2.5.69-bk15/net/ipv6/proc.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/proc.c	2003-05-23 04:36:23.000000000 -0700
@@ -291,10 +291,19 @@
 	return rc;
 
 proc_sockstat6_fail:
-	remove_proc_entry("dev_snmp6", proc_net);
+	proc_net_remove("dev_snmp6");
 proc_dev_snmp6_fail:
-	remove_proc_entry("snmp6", proc_net);
+	proc_net_remove("snmp6");
 proc_snmp6_fail:
 	rc = -ENOMEM;
 	goto out;
 }
+
+int ipv6_misc_proc_exit(void)
+{
+	proc_net_remove("sockstat6");
+	proc_net_remove("dev_snmp6");
+	proc_net_remove("snmp6");
+	return 0;
+}
+
diff -urN linux-2.5.69-bk15/net/ipv6/raw.c linux-2.5.69-bk16/net/ipv6/raw.c
--- linux-2.5.69-bk15/net/ipv6/raw.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/raw.c	2003-05-23 04:36:23.000000000 -0700
@@ -461,9 +461,9 @@
 		 * Only one fragment on the socket.
 		 */
 		/* should be check HW csum miyazawa */
-		*csum = csum_ipv6_magic(fl->fl6_src,
-					     fl->fl6_dst,
-					     len, fl->proto, skb->csum);
+		*csum = csum_ipv6_magic(&fl->fl6_src,
+					&fl->fl6_dst,
+					len, fl->proto, skb->csum);
 	} else {
 		u32 tmp_csum = 0;
 
@@ -471,9 +471,9 @@
 			tmp_csum = csum_add(tmp_csum, skb->csum);
 		}
 
-		tmp_csum = csum_ipv6_magic(fl->fl6_src,
-					fl->fl6_dst,
-					len, fl->proto, tmp_csum);
+		tmp_csum = csum_ipv6_magic(&fl->fl6_src,
+					   &fl->fl6_dst,
+					   len, fl->proto, tmp_csum);
 		*csum = tmp_csum;
 	}
 	if (*csum == 0)
@@ -540,7 +540,7 @@
 {
 	struct ipv6_txoptions opt_space;
 	struct sockaddr_in6 * sin6 = (struct sockaddr_in6 *) msg->msg_name;
-	struct in6_addr *daddr, *saddr = NULL;
+	struct in6_addr *daddr;
 	struct inet_opt *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct raw6_opt *raw_opt = raw6_sk(sk);
@@ -566,9 +566,7 @@
 	/*
 	 *	Get and verify the address. 
 	 */
-
-	fl.fl6_flowlabel = 0;
-	fl.oif = 0;
+	memset(&fl, 0, sizeof(fl));
 
 	if (sin6) {
 		if (addr_len < SIN6_LEN_RFC2133) 
@@ -628,7 +626,6 @@
 
 	if (fl.oif == 0)
 		fl.oif = sk->bound_dev_if;
-	fl.fl6_src = NULL;
 
 	if (msg->msg_controllen) {
 		opt = &opt_space;
@@ -653,26 +650,25 @@
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 
 	fl.proto = proto;
-	fl.fl6_dst = daddr;
-	if (fl.fl6_src == NULL && !ipv6_addr_any(&np->saddr))
-		fl.fl6_src = &np->saddr;
-	fl.fl_icmp_type = 0;
-	fl.fl_icmp_code = 0;
+	ipv6_addr_copy(&fl.fl6_dst, daddr);
+	if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
+		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
 
 	/* merge ip6_build_xmit from ip6_output */
 	if (opt && opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-		fl.fl6_dst = rt0->addr;
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 	}
 
-	if (!fl.oif && ipv6_addr_is_multicast(fl.nl_u.ip6_u.daddr))
+	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
 		fl.oif = np->mcast_oif;
 
-	err = ip6_dst_lookup(sk, &dst, &fl, &saddr);
-	if (err) goto out;
+	err = ip6_dst_lookup(sk, &dst, &fl);
+	if (err)
+		goto out;
 
 	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(fl.fl6_dst))
+		if (ipv6_addr_is_multicast(&fl.fl6_dst))
 			hlimit = np->mcast_hops;
 		else
 			hlimit = np->hop_limit;
@@ -702,14 +698,15 @@
 		}
 	}
 done:
-	ip6_dst_store(sk, dst, fl.nl_u.ip6_u.daddr == &np->daddr ? &np->daddr : NULL);
+	ip6_dst_store(sk, dst,
+		      !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
+		      &np->daddr : NULL);
 	if (err > 0)
 		err = np->recverr ? net_xmit_errno(err) : 0;
 
 	release_sock(sk);
 out:	
 	fl6_sock_release(flowlabel);
-	if (saddr) kfree(saddr);
 	return err<0?err:len;
 do_confirm:
 	dst_confirm(dst);
@@ -1061,6 +1058,6 @@
 
 void raw6_proc_exit(void)
 {
-	remove_proc_entry("raw6", proc_net);
+	proc_net_remove("raw6");
 }
 #endif	/* CONFIG_PROC_FS */
diff -urN linux-2.5.69-bk15/net/ipv6/route.c linux-2.5.69-bk16/net/ipv6/route.c
--- linux-2.5.69-bk15/net/ipv6/route.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/route.c	2003-05-23 04:36:23.000000000 -0700
@@ -454,12 +454,12 @@
 	int strict;
 	int attempts = 3;
 
-	strict = ipv6_addr_type(fl->fl6_dst) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL);
+	strict = ipv6_addr_type(&fl->fl6_dst) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL);
 
 relookup:
 	read_lock_bh(&rt6_lock);
 
-	fn = fib6_lookup(&ip6_routing_table, fl->fl6_dst, fl->fl6_src);
+	fn = fib6_lookup(&ip6_routing_table, &fl->fl6_dst, &fl->fl6_src);
 
 restart:
 	rt = fn->leaf;
@@ -481,7 +481,7 @@
 	if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) {
 		read_unlock_bh(&rt6_lock);
 
-		rt = rt6_cow(rt, fl->fl6_dst, fl->fl6_src);
+		rt = rt6_cow(rt, &fl->fl6_dst, &fl->fl6_src);
 
 		if (rt->u.dst.error != -EEXIST || --attempts <= 0)
 			goto out2;
@@ -1616,9 +1616,11 @@
 
 	memset(&fl, 0, sizeof(fl));
 	if (rta[RTA_SRC-1])
-		fl.fl6_src = (struct in6_addr*)RTA_DATA(rta[RTA_SRC-1]);
+		ipv6_addr_copy(&fl.fl6_src,
+			       (struct in6_addr*)RTA_DATA(rta[RTA_SRC-1]));
 	if (rta[RTA_DST-1])
-		fl.fl6_dst = (struct in6_addr*)RTA_DATA(rta[RTA_DST-1]);
+		ipv6_addr_copy(&fl.fl6_dst,
+			       (struct in6_addr*)RTA_DATA(rta[RTA_DST-1]));
 
 	if (rta[RTA_IIF-1])
 		memcpy(&iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int));
@@ -1642,7 +1644,7 @@
 
 	NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid;
 	err = rt6_fill_node(skb, rt, 
-			    fl.fl6_dst, fl.fl6_src,
+			    &fl.fl6_dst, &fl.fl6_src,
 			    iif,
 			    RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
 			    nlh->nlmsg_seq, nlh);
@@ -1929,7 +1931,7 @@
 {
 #ifdef CONFIG_PROC_FS
 	proc_net_remove("ipv6_route");
-	remove_proc_entry("rt6_stats", proc_net);
+	proc_net_remove("rt6_stats");
 #endif
 	xfrm6_fini();
 	rt6_ifdown(NULL);
diff -urN linux-2.5.69-bk15/net/ipv6/tcp_ipv6.c linux-2.5.69-bk16/net/ipv6/tcp_ipv6.c
--- linux-2.5.69-bk15/net/ipv6/tcp_ipv6.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/tcp_ipv6.c	2003-05-23 04:36:23.000000000 -0700
@@ -571,7 +571,8 @@
 	if (usin->sin6_family != AF_INET6) 
 		return(-EAFNOSUPPORT);
 
-	fl.fl6_flowlabel = 0;
+	memset(&fl, 0, sizeof(fl));
+
 	if (np->sndflow) {
 		fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
 		IP6_ECN_flow_init(fl.fl6_flowlabel);
@@ -666,20 +667,18 @@
 		saddr = &np->rcv_saddr;
 
 	fl.proto = IPPROTO_TCP;
-	fl.fl6_dst = &np->daddr;
-	fl.fl6_src = saddr;
+	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+	ipv6_addr_copy(&fl.fl6_src,
+		       (saddr ? saddr : &np->saddr));
 	fl.oif = sk->bound_dev_if;
 	fl.fl_ip_dport = usin->sin6_port;
 	fl.fl_ip_sport = inet->sport;
 
 	if (np->opt && np->opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
-		fl.fl6_dst = rt0->addr;
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 	}
 
-	if (!fl.fl6_src)
-		fl.fl6_src = &np->saddr;
-
 	dst = ip6_route_output(sk, &fl);
 
 	if ((err = dst->error) != 0) {
@@ -794,9 +793,10 @@
 			   to handle rthdr case. Ignore this complexity
 			   for now.
 			 */
+			memset(&fl, 0, sizeof(fl));
 			fl.proto = IPPROTO_TCP;
-			fl.fl6_dst = &np->daddr;
-			fl.fl6_src = &np->saddr;
+			ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+			ipv6_addr_copy(&fl.fl6_src, &np->saddr);
 			fl.oif = sk->bound_dev_if;
 			fl.fl_ip_dport = inet->dport;
 			fl.fl_ip_sport = inet->sport;
@@ -879,9 +879,10 @@
 	struct flowi fl;
 	int err = -1;
 
+	memset(&fl, 0, sizeof(fl));
 	fl.proto = IPPROTO_TCP;
-	fl.fl6_dst = &req->af.v6_req.rmt_addr;
-	fl.fl6_src = &req->af.v6_req.loc_addr;
+	ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr);
+	ipv6_addr_copy(&fl.fl6_src, &req->af.v6_req.loc_addr);
 	fl.fl6_flowlabel = 0;
 	fl.oif = req->af.v6_req.iif;
 	fl.fl_ip_dport = req->rmt_port;
@@ -900,7 +901,7 @@
 
 		if (opt && opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-			fl.fl6_dst = rt0->addr;
+			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 		}
 
 		dst = ip6_route_output(sk, &fl);
@@ -916,7 +917,7 @@
 					 &req->af.v6_req.loc_addr, &req->af.v6_req.rmt_addr,
 					 csum_partial((char *)th, skb->len, skb->csum));
 
-		fl.fl6_dst = &req->af.v6_req.rmt_addr;
+		ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr);
 		err = ip6_xmit(sk, skb, &fl, opt);
 		if (err == NET_XMIT_CN)
 			err = 0;
@@ -1018,11 +1019,11 @@
 
 	buff->csum = csum_partial((char *)t1, sizeof(*t1), 0);
 
-	fl.fl6_dst = &skb->nh.ipv6h->saddr;
-	fl.fl6_src = &skb->nh.ipv6h->daddr;
-	fl.fl6_flowlabel = 0;
+	memset(&fl, 0, sizeof(fl));
+	ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr);
+	ipv6_addr_copy(&fl.fl6_src, &skb->nh.ipv6h->daddr);
 
-	t1->check = csum_ipv6_magic(fl.fl6_src, fl.fl6_dst, 
+	t1->check = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst,
 				    sizeof(*t1), IPPROTO_TCP,
 				    buff->csum);
 
@@ -1082,11 +1083,11 @@
 
 	buff->csum = csum_partial((char *)t1, tot_len, 0);
 
-	fl.fl6_dst = &skb->nh.ipv6h->saddr;
-	fl.fl6_src = &skb->nh.ipv6h->daddr;
-	fl.fl6_flowlabel = 0;
+	memset(&fl, 0, sizeof(fl));
+	ipv6_addr_copy(&fl.fl6_dst, &skb->nh.ipv6h->saddr);
+	ipv6_addr_copy(&fl.fl6_src, &skb->nh.ipv6h->daddr);
 
-	t1->check = csum_ipv6_magic(fl.fl6_src, fl.fl6_dst, 
+	t1->check = csum_ipv6_magic(&fl.fl6_src, &fl.fl6_dst,
 				    tot_len, IPPROTO_TCP,
 				    buff->csum);
 
@@ -1261,7 +1262,6 @@
 {
 	struct ipv6_pinfo *newnp, *np = inet6_sk(sk);
 	struct tcp6_sock *newtcp6sk;
-	struct flowi fl;
 	struct inet_opt *newinet;
 	struct tcp_opt *newtp;
 	struct sock *newsk;
@@ -1330,14 +1330,16 @@
 	}
 
 	if (dst == NULL) {
+		struct flowi fl;
+
+		memset(&fl, 0, sizeof(fl));
 		fl.proto = IPPROTO_TCP;
-		fl.fl6_dst = &req->af.v6_req.rmt_addr;
+		ipv6_addr_copy(&fl.fl6_dst, &req->af.v6_req.rmt_addr);
 		if (opt && opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-			fl.fl6_dst = rt0->addr;
+			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 		}
-		fl.fl6_src = &req->af.v6_req.loc_addr;
-		fl.fl6_flowlabel = 0;
+		ipv6_addr_copy(&fl.fl6_src, &req->af.v6_req.loc_addr);
 		fl.oif = sk->bound_dev_if;
 		fl.fl_ip_dport = req->rmt_port;
 		fl.fl_ip_sport = inet_sk(sk)->sport;
@@ -1725,9 +1727,10 @@
 		struct inet_opt *inet = inet_sk(sk);
 		struct flowi fl;
 
+		memset(&fl, 0, sizeof(fl));
 		fl.proto = IPPROTO_TCP;
-		fl.fl6_dst = &np->daddr;
-		fl.fl6_src = &np->saddr;
+		ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
 		fl.fl6_flowlabel = np->flow_label;
 		fl.oif = sk->bound_dev_if;
 		fl.fl_ip_dport = inet->dport;
@@ -1735,7 +1738,7 @@
 
 		if (np->opt && np->opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-			fl.fl6_dst = rt0->addr;
+			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 		}
 
 		dst = ip6_route_output(sk, &fl);
@@ -1762,9 +1765,10 @@
 	struct flowi fl;
 	struct dst_entry *dst;
 
+	memset(&fl, 0, sizeof(fl));
 	fl.proto = IPPROTO_TCP;
-	fl.fl6_dst = &np->daddr;
-	fl.fl6_src = &np->saddr;
+	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+	ipv6_addr_copy(&fl.fl6_src, &np->saddr);
 	fl.fl6_flowlabel = np->flow_label;
 	IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
 	fl.oif = sk->bound_dev_if;
@@ -1773,7 +1777,7 @@
 
 	if (np->opt && np->opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-		fl.fl6_dst = rt0->addr;
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 	}
 
 	dst = __sk_dst_check(sk, np->dst_cookie);
@@ -1793,7 +1797,7 @@
 	skb->dst = dst_clone(dst);
 
 	/* Restore final destination back after routing done */
-	fl.fl6_dst = &np->daddr;
+	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
 
 	return ip6_xmit(sk, skb, &fl, np->opt);
 }
diff -urN linux-2.5.69-bk15/net/ipv6/udp.c linux-2.5.69-bk16/net/ipv6/udp.c
--- linux-2.5.69-bk15/net/ipv6/udp.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/udp.c	2003-05-23 04:36:23.000000000 -0700
@@ -270,7 +270,7 @@
 	if (usin->sin6_family != AF_INET6) 
 	  	return -EAFNOSUPPORT;
 
-	fl.fl6_flowlabel = 0;
+	memset(&fl, 0, sizeof(fl));
 	if (np->sndflow) {
 		fl.fl6_flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
 		if (fl.fl6_flowlabel&IPV6_FLOWLABEL_MASK) {
@@ -350,8 +350,8 @@
 	 */
 
 	fl.proto = IPPROTO_UDP;
-	fl.fl6_dst = &np->daddr;
-	fl.fl6_src = &saddr;
+	ipv6_addr_copy(&fl.fl6_dst, &np->daddr);
+	ipv6_addr_copy(&fl.fl6_src, &saddr);
 	fl.oif = sk->bound_dev_if;
 	fl.fl_ip_dport = inet->dport;
 	fl.fl_ip_sport = inet->sport;
@@ -362,11 +362,11 @@
 	if (flowlabel) {
 		if (flowlabel->opt && flowlabel->opt->srcrt) {
 			struct rt0_hdr *rt0 = (struct rt0_hdr *) flowlabel->opt->srcrt;
-			fl.fl6_dst = rt0->addr;
+			ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 		}
 	} else if (np->opt && np->opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *)np->opt->srcrt;
-		fl.fl6_dst = rt0->addr;
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 	}
 
 	dst = ip6_route_output(sk, &fl);
@@ -377,7 +377,7 @@
 		return err;
 	}
 
-	ip6_dst_store(sk, dst, fl.fl6_dst);
+	ip6_dst_store(sk, dst, &fl.fl6_dst);
 
 	/* get the source address used in the appropriate device */
 
@@ -784,8 +784,8 @@
 	if (skb_queue_len(&sk->write_queue) == 1) {
 		skb->csum = csum_partial((char *)uh,
 				sizeof(struct udphdr), skb->csum);
-		uh->check = csum_ipv6_magic(fl->fl6_src,
-					    fl->fl6_dst,
+		uh->check = csum_ipv6_magic(&fl->fl6_src,
+					    &fl->fl6_dst,
 					    up->len, fl->proto, skb->csum);
 	} else {
 		u32 tmp_csum = 0;
@@ -795,8 +795,8 @@
 		}
 		tmp_csum = csum_partial((char *)uh,
 				sizeof(struct udphdr), tmp_csum);
-                tmp_csum = csum_ipv6_magic(fl->fl6_src,
-					   fl->fl6_dst,
+                tmp_csum = csum_ipv6_magic(&fl->fl6_src,
+					   &fl->fl6_dst,
 					   up->len, fl->proto, tmp_csum);
                 uh->check = tmp_csum;
 
@@ -819,7 +819,7 @@
 	struct inet_opt *inet = inet_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) msg->msg_name;
-	struct in6_addr *daddr, *saddr = NULL;
+	struct in6_addr *daddr;
 	struct ipv6_txoptions *opt = NULL;
 	struct ip6_flowlabel *flowlabel = NULL;
 	struct flowi fl;
@@ -849,8 +849,7 @@
 	}
 	ulen += sizeof(struct udphdr);
 
-	fl.fl6_flowlabel = 0;
-	fl.oif = 0;
+	memset(&fl, 0, sizeof(fl));
 
 	if (sin6) {
 		if (sin6->sin6_family == AF_INET) {
@@ -919,7 +918,6 @@
 
 	if (!fl.oif)
 		fl.oif = sk->bound_dev_if;
-	fl.fl6_src = NULL;
 
 	if (msg->msg_controllen) {
 		opt = &opt_space;
@@ -944,26 +942,27 @@
 		opt = fl6_merge_options(&opt_space, flowlabel, opt);
 
 	fl.proto = IPPROTO_UDP;
-	fl.fl6_dst = daddr;
-	if (fl.fl6_src == NULL && !ipv6_addr_any(&np->saddr))
-		fl.fl6_src = &np->saddr;
+	ipv6_addr_copy(&fl.fl6_dst, daddr);
+	if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
+		ipv6_addr_copy(&fl.fl6_src, &np->saddr);
 	fl.fl_ip_dport = up->dport;
 	fl.fl_ip_sport = inet->sport;
 	
 	/* merge ip6_build_xmit from ip6_output */
 	if (opt && opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) opt->srcrt;
-		fl.fl6_dst = rt0->addr;
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 	}
 
-	if (!fl.oif && ipv6_addr_is_multicast(fl.nl_u.ip6_u.daddr))
+	if (!fl.oif && ipv6_addr_is_multicast(&fl.fl6_dst))
 		fl.oif = np->mcast_oif;
 
-	err = ip6_dst_lookup(sk, &dst, &fl, &saddr);
-	if (err) goto out;
+	err = ip6_dst_lookup(sk, &dst, &fl);
+	if (err)
+		goto out;
 
 	if (hlimit < 0) {
-		if (ipv6_addr_is_multicast(fl.fl6_dst))
+		if (ipv6_addr_is_multicast(&fl.fl6_dst))
 			hlimit = np->mcast_hops;
 		else
 			hlimit = np->hop_limit;
@@ -998,13 +997,14 @@
 	else if (!corkreq)
 		err = udp_v6_push_pending_frames(sk, up);
 
-	ip6_dst_store(sk, dst, fl.nl_u.ip6_u.daddr == &np->daddr ? &np->daddr : NULL);
+	ip6_dst_store(sk, dst,
+		      !ipv6_addr_cmp(&fl.fl6_dst, &np->daddr) ?
+		      &np->daddr : NULL);
 	if (err > 0)
 		err = np->recverr ? net_xmit_errno(err) : 0;
 	release_sock(sk);
 out:
 	fl6_sock_release(flowlabel);
-	if (saddr) kfree(saddr);
 	if (!err) {
 		UDP6_INC_STATS_USER(UdpOutDatagrams);
 		return len;
diff -urN linux-2.5.69-bk15/net/ipv6/xfrm6_policy.c linux-2.5.69-bk16/net/ipv6/xfrm6_policy.c
--- linux-2.5.69-bk15/net/ipv6/xfrm6_policy.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/xfrm6_policy.c	2003-05-23 04:36:23.000000000 -0700
@@ -60,8 +60,8 @@
 	read_lock_bh(&policy->lock);
 	for (dst = policy->bundles; dst; dst = dst->next) {
 		struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
-		if (!ipv6_addr_cmp(&xdst->u.rt6.rt6i_dst.addr, fl->fl6_dst) &&
-		    !ipv6_addr_cmp(&xdst->u.rt6.rt6i_src.addr, fl->fl6_src) &&
+		if (!ipv6_addr_cmp(&xdst->u.rt6.rt6i_dst.addr, &fl->fl6_dst) &&
+		    !ipv6_addr_cmp(&xdst->u.rt6.rt6i_src.addr, &fl->fl6_src) &&
 		    __xfrm6_bundle_ok(xdst, fl)) {
 			dst_clone(dst);
 			break;
@@ -82,8 +82,8 @@
 	struct dst_entry *dst, *dst_prev;
 	struct rt6_info *rt0 = (struct rt6_info*)(*dst_p);
 	struct rt6_info *rt  = rt0;
-	struct in6_addr *remote = fl->fl6_dst;
-	struct in6_addr *local  = fl->fl6_src;
+	struct in6_addr *remote = &fl->fl6_dst;
+	struct in6_addr *local  = &fl->fl6_src;
 	int i;
 	int err = 0;
 	int header_len = 0;
@@ -116,13 +116,15 @@
 		trailer_len += xfrm[i]->props.trailer_len;
 	}
 
-	if (ipv6_addr_cmp(remote, fl->fl6_dst)) {
-		struct flowi fl_tunnel = { .nl_u = { .ip6_u =
-						     { .daddr = remote,
-						       .saddr = local }
-					           }
-				         };
-		err = xfrm_dst_lookup((struct xfrm_dst**)&rt, &fl_tunnel, AF_INET6);
+	if (ipv6_addr_cmp(remote, &fl->fl6_dst)) {
+		struct flowi fl_tunnel;
+
+		memset(&fl_tunnel, 0, sizeof(fl_tunnel));
+		ipv6_addr_copy(&fl_tunnel.fl6_dst, remote);
+		ipv6_addr_copy(&fl_tunnel.fl6_src, local);
+
+		err = xfrm_dst_lookup((struct xfrm_dst **) &rt,
+				      &fl_tunnel, AF_INET6);
 		if (err)
 			goto error;
 	} else {
@@ -175,8 +177,8 @@
 	struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset);
 	u8 nexthdr = skb->nh.ipv6h->nexthdr;
 
-	fl->fl6_dst = &hdr->daddr;
-	fl->fl6_src = &hdr->saddr;
+	ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr);
+	ipv6_addr_copy(&fl->fl6_src, &hdr->saddr);
 
 	while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) {
 		switch (nexthdr) {
diff -urN linux-2.5.69-bk15/net/ipv6/xfrm6_state.c linux-2.5.69-bk16/net/ipv6/xfrm6_state.c
--- linux-2.5.69-bk15/net/ipv6/xfrm6_state.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/ipv6/xfrm6_state.c	2003-05-23 04:36:23.000000000 -0700
@@ -25,8 +25,8 @@
 {
 	/* Initialize temporary selector matching only
 	 * to current session. */
-	ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, fl->fl6_dst);
-	ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, fl->fl6_src);
+	ipv6_addr_copy((struct in6_addr *)&x->sel.daddr, &fl->fl6_dst);
+	ipv6_addr_copy((struct in6_addr *)&x->sel.saddr, &fl->fl6_src);
 	x->sel.dport = fl->fl_ip_dport;
 	x->sel.dport_mask = ~0;
 	x->sel.sport = fl->fl_ip_sport;
diff -urN linux-2.5.69-bk15/net/key/af_key.c linux-2.5.69-bk16/net/key/af_key.c
--- linux-2.5.69-bk15/net/key/af_key.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/key/af_key.c	2003-05-23 04:36:23.000000000 -0700
@@ -2244,6 +2244,7 @@
 	p->sadb_prop_len = sizeof(struct sadb_prop)/8;
 	p->sadb_prop_exttype = SADB_EXT_PROPOSAL;
 	p->sadb_prop_replay = 32;
+	memset(p->sadb_prop_reserved, 0, sizeof(p->sadb_prop_reserved));
 
 	for (i = 0; ; i++) {
 		struct xfrm_algo_desc *aalg = xfrm_aalg_get_byidx(i);
@@ -2275,6 +2276,7 @@
 	p->sadb_prop_len = sizeof(struct sadb_prop)/8;
 	p->sadb_prop_exttype = SADB_EXT_PROPOSAL;
 	p->sadb_prop_replay = 32;
+	memset(p->sadb_prop_reserved, 0, sizeof(p->sadb_prop_reserved));
 
 	for (i=0; ; i++) {
 		struct xfrm_algo_desc *ealg = xfrm_ealg_get_byidx(i);
diff -urN linux-2.5.69-bk15/net/sctp/ipv6.c linux-2.5.69-bk16/net/sctp/ipv6.c
--- linux-2.5.69-bk15/net/sctp/ipv6.c	2003-05-23 04:36:17.000000000 -0700
+++ linux-2.5.69-bk16/net/sctp/ipv6.c	2003-05-23 04:36:23.000000000 -0700
@@ -144,17 +144,19 @@
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct flowi fl;
 
+	memset(&fl, 0, sizeof(fl));
+
 	fl.proto = sk->protocol;
 
 	/* Fill in the dest address from the route entry passed with the skb
 	 * and the source address from the transport.
 	 */
-	fl.fl6_dst = &transport->ipaddr.v6.sin6_addr;
-	fl.fl6_src = &transport->saddr.v6.sin6_addr;
+	ipv6_addr_copy(&fl.fl6_dst, &transport->ipaddr.v6.sin6_addr);
+	ipv6_addr_copy(&fl.fl6_src, &transport->saddr.v6.sin6_addr);
 
 	fl.fl6_flowlabel = np->flow_label;
 	IP6_ECN_flow_xmit(sk, fl.fl6_flowlabel);
-	if (ipv6_addr_type(fl.fl6_src) & IPV6_ADDR_LINKLOCAL)
+	if (ipv6_addr_type(&fl.fl6_src) & IPV6_ADDR_LINKLOCAL)
 		fl.oif = transport->saddr.v6.sin6_scope_id;
 	else
 		fl.oif = sk->bound_dev_if;
@@ -163,14 +165,14 @@
 
 	if (np->opt && np->opt->srcrt) {
 		struct rt0_hdr *rt0 = (struct rt0_hdr *) np->opt->srcrt;
-		fl.nl_u.ip6_u.daddr = rt0->addr;
+		ipv6_addr_copy(&fl.fl6_dst, rt0->addr);
 	}
 
 	SCTP_DEBUG_PRINTK("%s: skb:%p, len:%d, "
 			  "src:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x "
 			  "dst:%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
 			  __FUNCTION__, skb, skb->len, 
-			  NIP6(*fl.fl6_src), NIP6(*fl.fl6_dst));
+			  NIP6(fl.fl6_src), NIP6(fl.fl6_dst));
 
 	SCTP_INC_STATS(SctpOutSCTPPacks);
 
@@ -185,17 +187,19 @@
 				  union sctp_addr *saddr)
 {
 	struct dst_entry *dst;
-	struct flowi fl = {
-		.nl_u = { .ip6_u = { .daddr = &daddr->v6.sin6_addr, } } };
+	struct flowi fl;
+
+	memset(&fl, 0, sizeof(fl));
+	ipv6_addr_copy(&fl.fl6_dst, &daddr->v6.sin6_addr);
 
 	SCTP_DEBUG_PRINTK("%s: DST=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x ",
-			  __FUNCTION__, NIP6(*fl.fl6_dst));
+			  __FUNCTION__, NIP6(fl.fl6_dst));
 
 	if (saddr) {
-		fl.fl6_src = &saddr->v6.sin6_addr;
+		ipv6_addr_copy(&fl.fl6_src, &saddr->v6.sin6_addr);
 		SCTP_DEBUG_PRINTK(
 			"SRC=%04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x - ",
-			NIP6(*fl.fl6_src));
+			NIP6(fl.fl6_src));
 	}
 
 	dst = ip6_route_output(NULL, &fl);
diff -urN linux-2.5.69-bk15/net/wanrouter/wanmain.c linux-2.5.69-bk16/net/wanrouter/wanmain.c
--- linux-2.5.69-bk15/net/wanrouter/wanmain.c	2003-05-23 04:36:18.000000000 -0700
+++ linux-2.5.69-bk16/net/wanrouter/wanmain.c	2003-05-23 04:36:23.000000000 -0700
@@ -127,18 +127,21 @@
  *	WAN device IOCTL handlers
  */
 
-static int device_setup(struct wan_device *wandev, wandev_conf_t *u_conf);
-static int device_stat(struct wan_device *wandev, wandev_stat_t *u_stat);
-static int device_shutdown(struct wan_device *wandev);
-static int device_new_if(struct wan_device *wandev, wanif_conf_t *u_conf);
-static int device_del_if(struct wan_device *wandev, char *u_name);
+static int wanrouter_device_setup(struct wan_device *wandev,
+				  wandev_conf_t *u_conf);
+static int wanrouter_device_stat(struct wan_device *wandev,
+				 wandev_stat_t *u_stat);
+static int wanrouter_device_shutdown(struct wan_device *wandev);
+static int wanrouter_device_new_if(struct wan_device *wandev,
+				   wanif_conf_t *u_conf);
+static int wanrouter_device_del_if(struct wan_device *wandev, char *u_name);
 
 /*
  *	Miscellaneous
  */
 
-static struct wan_device *find_device (char *name);
-static int delete_interface (struct wan_device *wandev, char *name);
+static struct wan_device *wanrouter_find_device(char *name);
+static int wanrouter_delete_interface(struct wan_device *wandev, char *name);
 void lock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
 void unlock_adapter_irq(spinlock_t *lock, unsigned long *smp_flags);
 
@@ -148,19 +151,18 @@
  *	Global Data
  */
 
-static char fullname[]	= "Sangoma WANPIPE Router";
-static char copyright[]	= "(c) 1995-2000 Sangoma Technologies Inc.";
-static char modname[]   = ROUTER_NAME;	/* short module name */
-struct wan_device* router_devlist;	/* list of registered devices */
-static int devcnt;
+static char wanrouter_fullname[]  = "Sangoma WANPIPE Router";
+static char wanrouter_copyright[] = "(c) 1995-2000 Sangoma Technologies Inc.";
+static char wanrouter_modname[] = ROUTER_NAME; /* short module name */
+struct wan_device* wanrouter_router_devlist; /* list of registered devices */
 
 /*
  *	Organize Unique Identifiers for encapsulation/decapsulation
  */
 
-static unsigned char oui_ether[] = { 0x00, 0x00, 0x00 };
+static unsigned char wanrouter_oui_ether[] = { 0x00, 0x00, 0x00 };
 #if 0
-static unsigned char oui_802_2[] = { 0x00, 0x80, 0xC2 };
+static unsigned char wanrouter_oui_802_2[] = { 0x00, 0x80, 0xC2 };
 #endif
 
 #ifndef MODULE
@@ -172,12 +174,13 @@
 	extern int sdladrv_init(void);
 
 	printk(KERN_INFO "%s v%u.%u %s\n",
-		fullname, ROUTER_VERSION, ROUTER_RELEASE, copyright);
+	       wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE,
+	       wanrouter_copyright);
 
 	err = wanrouter_proc_init();
-	if (err){
-		printk(KERN_INFO "%s: can't create entry in proc filesystem!\n", modname);
-	}
+	if (err)
+		printk(KERN_INFO "%s: can't create entry in proc filesystem!\n",
+		       wanrouter_modname);
 
         /*
          *      Initialise compiled in boards
@@ -218,14 +221,14 @@
 	int err;
 
 	printk(KERN_INFO "%s v%u.%u %s\n",
-		fullname, ROUTER_VERSION, ROUTER_RELEASE, copyright);
+	       wanrouter_fullname, ROUTER_VERSION, ROUTER_RELEASE,
+	       wanrouter_copyright);
 
 	err = wanrouter_proc_init();
 
-	if (err){
-		printk(KERN_INFO
-		"%s: can't create entry in proc filesystem!\n", modname);
-	}
+	if (err)
+		printk(KERN_INFO "%s: can't create entry in proc filesystem!\n",
+		       wanrouter_modname);
 	return err;
 }
 
@@ -274,12 +277,12 @@
 	if (!namelen || (namelen > WAN_DRVNAME_SZ))
 		return -EINVAL;
 
-	if (find_device(wandev->name) != NULL)
+	if (wanrouter_find_device(wandev->name))
 		return -EEXIST;
 
 #ifdef WANDEBUG
 	printk(KERN_INFO "%s: registering WAN device %s\n",
-		modname, wandev->name);
+	       wanrouter_modname, wandev->name);
 #endif
 
 	/*
@@ -289,7 +292,7 @@
 	if (err) {
 		printk(KERN_INFO
 			"%s: can't create /proc/net/router/%s entry!\n",
-			modname, wandev->name);
+			wanrouter_modname, wandev->name);
 		return err;
 	}
 
@@ -300,9 +303,8 @@
 
 	wandev->ndev = 0;
 	wandev->dev  = NULL;
-	wandev->next = router_devlist;
-	router_devlist = wandev;
-	++devcnt;
+	wandev->next = wanrouter_router_devlist;
+	wanrouter_router_devlist = wandev;
         MOD_INC_USE_COUNT;	/* prevent module from unloading */
 	return 0;
 }
@@ -327,7 +329,7 @@
 	if (name == NULL)
 		return -EINVAL;
 
-	for (wandev = router_devlist, prev = NULL;
+	for (wandev = wanrouter_router_devlist, prev = NULL;
 		wandev && strcmp(wandev->name, name);
 		prev = wandev, wandev = wandev->next)
 		;
@@ -335,18 +337,18 @@
 		return -ENODEV;
 
 #ifdef WANDEBUG
-	printk(KERN_INFO "%s: unregistering WAN device %s\n", modname, name);
+	printk(KERN_INFO "%s: unregistering WAN device %s\n",
+	       wanrouter_modname, name);
 #endif
 
 	if (wandev->state != WAN_UNCONFIGURED)
-		device_shutdown(wandev);
+		wanrouter_device_shutdown(wandev);
 
 	if (prev)
 		prev->next = wandev->next;
 	else
-		router_devlist = wandev->next;
+		wanrouter_router_devlist = wandev->next;
 
-	--devcnt;
 	wanrouter_proc_delete(wandev);
         MOD_DEC_USE_COUNT;
 	return 0;
@@ -381,14 +383,15 @@
 		skb_push(skb, 7);
 		skb->data[0] = 0;
 		skb->data[1] = NLPID_SNAP;
-		memcpy(&skb->data[2], oui_ether, sizeof(oui_ether));
+		memcpy(&skb->data[2], wanrouter_oui_ether,
+		       sizeof(wanrouter_oui_ether));
 		*((unsigned short*)&skb->data[5]) = htons(type);
 		break;
 
 	default:		/* Unknown packet type */
 		printk(KERN_INFO
 			"%s: unsupported Ethertype 0x%04X on interface %s!\n",
-			modname, type, dev->name);
+			wanrouter_modname, type, dev->name);
 		hdr_len = -EINVAL;
 	}
 	return hdr_len;
@@ -418,10 +421,11 @@
 		break;
 
         case NLPID_SNAP:	/* SNAP encapsulation */
-		if (memcmp(&skb->data[cnt + 1], oui_ether, sizeof(oui_ether))){
+		if (memcmp(&skb->data[cnt + 1], wanrouter_oui_ether,
+			   sizeof(wanrouter_oui_ether))){
           		printk(KERN_INFO
 				"%s: unsupported SNAP OUI %02X-%02X-%02X "
-				"on interface %s!\n", modname,
+				"on interface %s!\n", wanrouter_modname,
 				skb->data[cnt+1], skb->data[cnt+2],
 				skb->data[cnt+3], dev->name);
 			return 0;
@@ -435,7 +439,7 @@
 	default:
 		printk(KERN_INFO
 			"%s: unsupported NLPID 0x%02X on interface %s!\n",
-			modname, skb->data[cnt], dev->name);
+			wanrouter_modname, skb->data[cnt], dev->name);
 		return 0;
 	}
 	skb->protocol = ethertype;
@@ -475,23 +479,23 @@
 
 	switch (cmd) {
 	case ROUTER_SETUP:
-		err = device_setup(wandev, (void*)arg);
+		err = wanrouter_device_setup(wandev, (void*)arg);
 		break;
 
 	case ROUTER_DOWN:
-		err = device_shutdown(wandev);
+		err = wanrouter_device_shutdown(wandev);
 		break;
 
 	case ROUTER_STAT:
-		err = device_stat(wandev, (void*)arg);
+		err = wanrouter_device_stat(wandev, (void*)arg);
 		break;
 
 	case ROUTER_IFNEW:
-		err = device_new_if(wandev, (void*)arg);
+		err = wanrouter_device_new_if(wandev, (void*)arg);
 		break;
 
 	case ROUTER_IFDEL:
-		err = device_del_if(wandev, (void*)arg);
+		err = wanrouter_device_del_if(wandev, (void*)arg);
 		break;
 
 	case ROUTER_IFSTAT:
@@ -519,7 +523,8 @@
  *	o call driver's setup() entry point
  */
 
-static int device_setup(struct wan_device *wandev, wandev_conf_t *u_conf)
+static int wanrouter_device_setup(struct wan_device *wandev,
+				  wandev_conf_t *u_conf)
 {
 	void *data = NULL;
 	wandev_conf_t *conf;
@@ -595,7 +600,7 @@
  *	o call driver's shutdown() entry point
  */
 
-static int device_shutdown(struct wan_device *wandev)
+static int wanrouter_device_shutdown(struct wan_device *wandev)
 {
 	struct net_device *dev;
 	int err=0;
@@ -606,7 +611,8 @@
 	printk(KERN_INFO "\n%s: Shutting Down!\n",wandev->name);
 
 	for (dev = wandev->dev; dev;) {
-		if ((err=delete_interface(wandev, dev->name)) != 0)
+		err = wanrouter_delete_interface(wandev, dev->name);
+		if (err)
 			return err;
 		/* The above function deallocates the current dev
 		 * structure. Therefore, we cannot use dev->priv
@@ -628,7 +634,8 @@
  *	Get WAN device status & statistics.
  */
 
-static int device_stat(struct wan_device *wandev, wandev_stat_t *u_stat)
+static int wanrouter_device_stat(struct wan_device *wandev,
+				 wandev_stat_t *u_stat)
 {
 	wandev_stat_t stat;
 
@@ -658,7 +665,8 @@
  *	o register network interface
  */
 
-static int device_new_if(struct wan_device *wandev, wanif_conf_t *u_conf)
+static int wanrouter_device_new_if(struct wan_device *wandev,
+				   wanif_conf_t *u_conf)
 {
 	wanif_conf_t conf;
 	struct net_device *dev = NULL;
@@ -718,7 +726,7 @@
 
 			#ifdef WANDEBUG
 			printk(KERN_INFO "%s: registering interface %s...\n",
-				modname, dev->name);
+				wanrouter_modname, dev->name);
 			#endif
 
 			err = register_netdev(dev);
@@ -775,7 +783,7 @@
  *	 o copy configuration data to kernel address space
  */
 
-static int device_del_if(struct wan_device *wandev, char *u_name)
+static int wanrouter_device_del_if(struct wan_device *wandev, char *u_name)
 {
 	char name[WAN_IFNAME_SZ + 1];
         int err = 0;
@@ -788,7 +796,7 @@
 	if (copy_from_user(name, u_name, WAN_IFNAME_SZ))
 		return -EFAULT;
 
-	err = delete_interface(wandev, name);
+	err = wanrouter_delete_interface(wandev, name);
 	if (err)
 		return err;
 
@@ -816,11 +824,12 @@
  *	Return pointer to the WAN device data space or NULL if device not found.
  */
 
-static struct wan_device *find_device(char *name)
+static struct wan_device *wanrouter_find_device(char *name)
 {
 	struct wan_device *wandev;
 
-	for (wandev = router_devlist;wandev && strcmp(wandev->name, name);
+	for (wandev = wanrouter_router_devlist;
+	     wandev && strcmp(wandev->name, name);
 		wandev = wandev->next);
 	return wandev;
 }
@@ -842,7 +851,7 @@
  *	sure that opened interfaces are not removed!
  */
 
-static int delete_interface(struct wan_device *wandev, char *name)
+static int wanrouter_delete_interface(struct wan_device *wandev, char *name)
 {
 	struct net_device *dev = NULL, *prev = NULL;
 	unsigned long smp_flags=0;
diff -urN linux-2.5.69-bk15/net/xfrm/xfrm_policy.c linux-2.5.69-bk16/net/xfrm/xfrm_policy.c
--- linux-2.5.69-bk15/net/xfrm/xfrm_policy.c	2003-05-23 04:36:18.000000000 -0700
+++ linux-2.5.69-bk16/net/xfrm/xfrm_policy.c	2003-05-23 04:36:23.000000000 -0700
@@ -314,7 +314,7 @@
 	return pol;
 }
 
-void xfrm_policy_flush()
+void xfrm_policy_flush(void)
 {
 	struct xfrm_policy *xp;
 	int dir;
