diff --git a/Makefile b/Makefile
index d165e80..7d2f304 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 20
-EXTRAVERSION = .2
+EXTRAVERSION = .3
 NAME = Homicidal Dwarf Hamster
 
 # *DOCUMENTATION*
diff --git a/arch/sparc/kernel/of_device.c b/arch/sparc/kernel/of_device.c
index dab6169..798b140 100644
--- a/arch/sparc/kernel/of_device.c
+++ b/arch/sparc/kernel/of_device.c
@@ -495,7 +495,7 @@ static void __init build_device_resources(struct of_device 
*op,
                u32 *reg = (preg + (index * ((na + ns) * 4)));
                struct device_node *dp = op->node;
                struct device_node *pp = p_op->node;
-               struct of_bus *pbus;
+               struct of_bus *pbus, *dbus;
                u64 size, result = OF_BAD_ADDR;
                unsigned long flags;
                int dna, dns;
@@ -516,6 +516,7 @@ static void __init build_device_resources(struct of_device 
*op,
 
                dna = na;
                dns = ns;
+               dbus = bus;
 
                while (1) {
                        dp = pp;
@@ -528,13 +529,13 @@ static void __init build_device_resources(struct 
of_device *op,
                        pbus = of_match_bus(pp);
                        pbus->count_cells(dp, &pna, &pns);
 
-                       if (build_one_resource(dp, bus, pbus, addr,
+                       if (build_one_resource(dp, dbus, pbus, addr,
                                               dna, dns, pna))
                                break;
 
                        dna = pna;
                        dns = pns;
-                       bus = pbus;
+                       dbus = pbus;
                }
 
        build_res:
diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
index ad74e5e..1f45985 100644
--- a/arch/sparc64/kernel/of_device.c
+++ b/arch/sparc64/kernel/of_device.c
@@ -581,7 +581,7 @@ static void __init build_device_resources(struct of_device 
*op,
                u32 *reg = (preg + (index * ((na + ns) * 4)));
                struct device_node *dp = op->node;
                struct device_node *pp = p_op->node;
-               struct of_bus *pbus;
+               struct of_bus *pbus, *dbus;
                u64 size, result = OF_BAD_ADDR;
                unsigned long flags;
                int dna, dns;
@@ -599,6 +599,7 @@ static void __init build_device_resources(struct of_device 
*op,
 
                dna = na;
                dns = ns;
+               dbus = bus;
 
                while (1) {
                        dp = pp;
@@ -611,13 +612,13 @@ static void __init build_device_resources(struct 
of_device *op,
                        pbus = of_match_bus(pp);
                        pbus->count_cells(dp, &pna, &pns);
 
-                       if (build_one_resource(dp, bus, pbus, addr,
+                       if (build_one_resource(dp, dbus, pbus, addr,
                                               dna, dns, pna))
                                break;
 
                        dna = pna;
                        dns = pns;
-                       bus = pbus;
+                       dbus = pbus;
                }
 
        build_res:
diff --git a/drivers/connector/connector.c b/drivers/connector/connector.c
index a44db75..a905f78 100644
--- a/drivers/connector/connector.c
+++ b/drivers/connector/connector.c
@@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(cn_netlink_send);
  */
 static int cn_call_callback(struct cn_msg *msg, void (*destruct_data)(void *), 
void *data)
 {
-       struct cn_callback_entry *__cbq;
+       struct cn_callback_entry *__cbq, *__new_cbq;
        struct cn_dev *dev = &cdev;
        int err = -ENODEV;
 
@@ -148,27 +148,27 @@ static int cn_call_callback(struct cn_msg *msg, void 
(*destruct_data)(void *), v
                        } else {
                                struct cn_callback_data *d;
                                
-                               __cbq = kzalloc(sizeof(*__cbq), GFP_ATOMIC);
-                               if (__cbq) {
-                                       d = &__cbq->data;
+                               err = -ENOMEM;
+                               __new_cbq = kzalloc(sizeof(struct 
cn_callback_entry), GFP_ATOMIC);
+                               if (__new_cbq) {
+                                       d = &__new_cbq->data;
                                        d->callback_priv = msg;
                                        d->callback = __cbq->data.callback;
                                        d->ddata = data;
                                        d->destruct_data = destruct_data;
-                                       d->free = __cbq;
+                                       d->free = __new_cbq;
 
-                                       INIT_WORK(&__cbq->work,
+                                       INIT_WORK(&__new_cbq->work,
                                                        &cn_queue_wrapper);
-                                       
+
                                        if (queue_work(dev->cbdev->cn_queue,
-                                                   &__cbq->work))
+                                                   &__new_cbq->work))
                                                err = 0;
                                        else {
-                                               kfree(__cbq);
+                                               kfree(__new_cbq);
                                                err = -EINVAL;
                                        }
-                               } else
-                                       err = -ENOMEM;
+                               }
                        }
                        break;
                }
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h 
b/drivers/net/wireless/bcm43xx/bcm43xx.h
index 02ad9b1..38ea6b9 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h
@@ -766,6 +766,7 @@ struct bcm43xx_private {
         * This is currently always BCM43xx_BUSTYPE_PCI
         */
        u8 bustype;
+       u64 dma_mask;
 
        u16 board_vendor;
        u16 board_type;
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c 
b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
index 978ed09..6e0dc76 100644
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c
@@ -145,16 +145,14 @@ dma_addr_t map_descbuffer(struct bcm43xx_dmaring *ring,
                          int tx)
 {
        dma_addr_t dmaaddr;
+       int direction = PCI_DMA_FROMDEVICE;
 
-       if (tx) {
-               dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
-                                        buf, len,
-                                        DMA_TO_DEVICE);
-       } else {
-               dmaaddr = dma_map_single(&ring->bcm->pci_dev->dev,
+       if (tx)
+               direction = PCI_DMA_TODEVICE;
+
+       dmaaddr = pci_map_single(ring->bcm->pci_dev,
                                         buf, len,
-                                        DMA_FROM_DEVICE);
-       }
+                                        direction);
 
        return dmaaddr;
 }
@@ -166,13 +164,13 @@ void unmap_descbuffer(struct bcm43xx_dmaring *ring,
                      int tx)
 {
        if (tx) {
-               dma_unmap_single(&ring->bcm->pci_dev->dev,
+               pci_unmap_single(ring->bcm->pci_dev,
                                 addr, len,
-                                DMA_TO_DEVICE);
+                                PCI_DMA_TODEVICE);
        } else {
-               dma_unmap_single(&ring->bcm->pci_dev->dev,
+               pci_unmap_single(ring->bcm->pci_dev,
                                 addr, len,
-                                DMA_FROM_DEVICE);
+                                PCI_DMA_FROMDEVICE);
        }
 }
 
@@ -183,8 +181,8 @@ void sync_descbuffer_for_cpu(struct bcm43xx_dmaring *ring,
 {
        assert(!ring->tx);
 
-       dma_sync_single_for_cpu(&ring->bcm->pci_dev->dev,
-                               addr, len, DMA_FROM_DEVICE);
+       pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
+                                   addr, len, PCI_DMA_FROMDEVICE);
 }
 
 static inline
@@ -194,8 +192,8 @@ void sync_descbuffer_for_device(struct bcm43xx_dmaring 
*ring,
 {
        assert(!ring->tx);
 
-       dma_sync_single_for_device(&ring->bcm->pci_dev->dev,
-                                  addr, len, DMA_FROM_DEVICE);
+       pci_dma_sync_single_for_cpu(ring->bcm->pci_dev,
+                                   addr, len, PCI_DMA_TODEVICE);
 }
 
 /* Unmap and free a descriptor buffer. */
@@ -214,17 +212,53 @@ void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
 
 static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
 {
-       struct device *dev = &(ring->bcm->pci_dev->dev);
-
-       ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
-                                           &(ring->dmabase), GFP_KERNEL);
+       ring->descbase = pci_alloc_consistent(ring->bcm->pci_dev, 
BCM43xx_DMA_RINGMEMSIZE,
+                                           &(ring->dmabase));
        if (!ring->descbase) {
-               printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
-               return -ENOMEM;
+               /* Allocation may have failed due to pci_alloc_consistent
+                  insisting on use of GFP_DMA, which is more restrictive
+                  than necessary...  */
+               struct dma_desc *rx_ring;
+               dma_addr_t rx_ring_dma;
+
+               rx_ring = kzalloc(BCM43xx_DMA_RINGMEMSIZE, GFP_KERNEL);
+               if (!rx_ring)
+                       goto out_err;
+
+               rx_ring_dma = pci_map_single(ring->bcm->pci_dev, rx_ring,
+                                            BCM43xx_DMA_RINGMEMSIZE,
+                                            PCI_DMA_BIDIRECTIONAL);
+
+               if (pci_dma_mapping_error(rx_ring_dma) ||
+                   rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > 
ring->bcm->dma_mask) {
+                       /* Sigh... */
+                       if (!pci_dma_mapping_error(rx_ring_dma))
+                               pci_unmap_single(ring->bcm->pci_dev,
+                                                rx_ring_dma, 
BCM43xx_DMA_RINGMEMSIZE,
+                                                PCI_DMA_BIDIRECTIONAL);
+                       rx_ring_dma = pci_map_single(ring->bcm->pci_dev,
+                                                rx_ring, 
BCM43xx_DMA_RINGMEMSIZE,
+                                                PCI_DMA_BIDIRECTIONAL);
+                       if (pci_dma_mapping_error(rx_ring_dma) ||
+                           rx_ring_dma + BCM43xx_DMA_RINGMEMSIZE > 
ring->bcm->dma_mask) {
+                               assert(0);
+                               if (!pci_dma_mapping_error(rx_ring_dma))
+                                       pci_unmap_single(ring->bcm->pci_dev,
+                                                        rx_ring_dma, 
BCM43xx_DMA_RINGMEMSIZE,
+                                                        PCI_DMA_BIDIRECTIONAL);
+                               goto out_err;
+                       }
+                }
+
+                ring->descbase = rx_ring;
+                ring->dmabase = rx_ring_dma;
        }
        memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
 
        return 0;
+out_err:
+       printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
+       return -ENOMEM;
 }
 
 static void free_ringmemory(struct bcm43xx_dmaring *ring)
@@ -407,6 +441,29 @@ static int setup_rx_descbuffer(struct bcm43xx_dmaring 
*ring,
        if (unlikely(!skb))
                return -ENOMEM;
        dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
+       /* This hardware bug work-around adapted from the b44 driver.
+          The chip may be unable to do PCI DMA to/from anything above 1GB */
+       if (pci_dma_mapping_error(dmaaddr) ||
+           dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
+               /* This one has 30-bit addressing... */
+               if (!pci_dma_mapping_error(dmaaddr))
+                       pci_unmap_single(ring->bcm->pci_dev,
+                                        dmaaddr, ring->rx_buffersize,
+                                        PCI_DMA_FROMDEVICE);
+               dev_kfree_skb_any(skb);
+               skb = __dev_alloc_skb(ring->rx_buffersize,GFP_DMA);
+               if (skb == NULL)
+                       return -ENOMEM;
+               dmaaddr = pci_map_single(ring->bcm->pci_dev,
+                                        skb->data, ring->rx_buffersize,
+                                        PCI_DMA_FROMDEVICE);
+               if (pci_dma_mapping_error(dmaaddr) ||
+                   dmaaddr + ring->rx_buffersize > ring->bcm->dma_mask) {
+                       assert(0);
+                       dev_kfree_skb_any(skb);
+                       return -ENOMEM;
+               }
+       }
        meta->skb = skb;
        meta->dmaaddr = dmaaddr;
        skb->dev = ring->bcm->net_dev;
@@ -636,8 +693,10 @@ struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct 
bcm43xx_private *bcm,
        err = dmacontroller_setup(ring);
        if (err)
                goto err_free_ringmemory;
+       return ring;
 
 out:
+       printk(KERN_ERR PFX "Error in bcm43xx_setup_dmaring\n");
        return ring;
 
 err_free_ringmemory:
@@ -705,30 +764,16 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
        struct bcm43xx_dmaring *ring;
        int err = -ENOMEM;
        int dma64 = 0;
-       u64 mask = bcm43xx_get_supported_dma_mask(bcm);
-       int nobits;
 
-       if (mask == DMA_64BIT_MASK) {
+       bcm->dma_mask = bcm43xx_get_supported_dma_mask(bcm);
+       if (bcm->dma_mask == DMA_64BIT_MASK)
                dma64 = 1;
-               nobits = 64;
-       } else if (mask == DMA_32BIT_MASK)
-               nobits = 32;
-       else
-               nobits = 30;
-       err = pci_set_dma_mask(bcm->pci_dev, mask);
-       err |= pci_set_consistent_dma_mask(bcm->pci_dev, mask);
-       if (err) {
-#ifdef CONFIG_BCM43XX_PIO
-               printk(KERN_WARNING PFX "DMA not supported on this device."
-                                       " Falling back to PIO.\n");
-               bcm->__using_pio = 1;
-               return -ENOSYS;
-#else
-               printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not 
configured. "
-                                   "Please recompile the driver with PIO 
support.\n");
-               return -ENODEV;
-#endif /* CONFIG_BCM43XX_PIO */
-       }
+       err = pci_set_dma_mask(bcm->pci_dev, bcm->dma_mask);
+       if (err)
+               goto no_dma;
+       err = pci_set_consistent_dma_mask(bcm->pci_dev, bcm->dma_mask);
+       if (err)
+               goto no_dma;
 
        /* setup TX DMA channels. */
        ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
@@ -774,7 +819,9 @@ int bcm43xx_dma_init(struct bcm43xx_private *bcm)
                dma->rx_ring3 = ring;
        }
 
-       dprintk(KERN_INFO PFX "%d-bit DMA initialized\n", nobits);
+       dprintk(KERN_INFO PFX "%d-bit DMA initialized\n",
+               (bcm->dma_mask == DMA_64BIT_MASK) ? 64 :
+               (bcm->dma_mask == DMA_32BIT_MASK) ? 32 : 30);
        err = 0;
 out:
        return err;
@@ -800,7 +847,17 @@ err_destroy_tx1:
 err_destroy_tx0:
        bcm43xx_destroy_dmaring(dma->tx_ring0);
        dma->tx_ring0 = NULL;
-       goto out;
+no_dma:
+#ifdef CONFIG_BCM43XX_PIO
+       printk(KERN_WARNING PFX "DMA not supported on this device."
+                               " Falling back to PIO.\n");
+       bcm->__using_pio = 1;
+       return -ENOSYS;
+#else
+       printk(KERN_ERR PFX "FATAL: DMA not supported and PIO not configured. "
+                           "Please recompile the driver with PIO support.\n");
+       return -ENODEV;
+#endif /* CONFIG_BCM43XX_PIO */
 }
 
 /* Generate a cookie for the TX header. */
@@ -905,6 +962,7 @@ static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
        struct bcm43xx_dmadesc_generic *desc;
        struct bcm43xx_dmadesc_meta *meta;
        dma_addr_t dmaaddr;
+       struct sk_buff *bounce_skb;
 
        assert(skb_shinfo(skb)->nr_frags == 0);
 
@@ -924,9 +982,28 @@ static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
                               skb->len - sizeof(struct bcm43xx_txhdr),
                               (cur_frag == 0),
                               generate_cookie(ring, slot));
+       dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
+       if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > 
ring->bcm->dma_mask) {
+               /* chip cannot handle DMA to/from > 1GB, use bounce buffer 
(copied from b44 driver) */
+               if (!dma_mapping_error(dmaaddr))
+                       unmap_descbuffer(ring, dmaaddr, skb->len, 1);
+               bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC|GFP_DMA);
+               if (!bounce_skb)
+                       return;
+               dmaaddr = map_descbuffer(ring, bounce_skb->data, 
bounce_skb->len, 1);
+               if (dma_mapping_error(dmaaddr) || dmaaddr + skb->len > 
ring->bcm->dma_mask) {
+                       if (!dma_mapping_error(dmaaddr))
+                               unmap_descbuffer(ring, dmaaddr, skb->len, 1);
+                       dev_kfree_skb_any(bounce_skb);
+                       assert(0);
+                       return;
+               }
+               memcpy(skb_put(bounce_skb, skb->len), skb->data, skb->len);
+               dev_kfree_skb_any(skb);
+               skb = bounce_skb;
+       }
 
        meta->skb = skb;
-       dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
        meta->dmaaddr = dmaaddr;
 
        fill_descriptor(ring, desc, dmaaddr,
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 30ee3d7..614c2c9 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -954,7 +954,9 @@ static int resp_inquiry(struct scsi_cmnd * scp, int target,
        int alloc_len, n, ret;
 
        alloc_len = (cmd[3] << 8) + cmd[4];
-       arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_KERNEL);
+       arr = kzalloc(SDEBUG_MAX_INQ_ARR_SZ, GFP_ATOMIC);
+       if (! arr)
+               return DID_REQUEUE << 16;
        if (devip->wlun)
                pq_pdt = 0x1e;  /* present, wlun */
        else if (scsi_debug_no_lun_0 && (0 == devip->lun))
@@ -1217,7 +1219,9 @@ static int resp_report_tgtpgs(struct scsi_cmnd * scp,
        alen = ((cmd[6] << 24) + (cmd[7] << 16) + (cmd[8] << 8)
                + cmd[9]);
 
-       arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_KERNEL);
+       arr = kzalloc(SDEBUG_MAX_TGTPGS_ARR_SZ, GFP_ATOMIC);
+       if (! arr)
+               return DID_REQUEUE << 16;
        /*
         * EVPD page 0x88 states we have two ports, one
         * real and a fake port with no device connected.
@@ -1996,6 +2000,8 @@ static int scsi_debug_slave_configure(struct scsi_device 
* sdp)
        if (sdp->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN)
                sdp->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN;
        devip = devInfoReg(sdp);
+       if (NULL == devip)
+               return 1;       /* no resources, will be marked offline */
        sdp->hostdata = devip;
        if (sdp->host->cmd_per_lun)
                scsi_adjust_queue_depth(sdp, SDEBUG_TAGGED_QUEUING,
@@ -2044,7 +2050,7 @@ static struct sdebug_dev_info * devInfoReg(struct 
scsi_device * sdev)
                }
        }
        if (NULL == open_devip) { /* try and make a new one */
-               open_devip = kzalloc(sizeof(*open_devip),GFP_KERNEL);
+               open_devip = kzalloc(sizeof(*open_devip),GFP_ATOMIC);
                if (NULL == open_devip) {
                        printk(KERN_ERR "%s: out of memory at line %d\n",
                                __FUNCTION__, __LINE__);
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 9d2fdfd..e6966f1 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -1275,11 +1275,31 @@ static int keyspan_fake_startup (struct usb_serial 
*serial)
 }
 
 /* Helper functions used by keyspan_setup_urbs */
+static struct usb_endpoint_descriptor const *find_ep(struct usb_serial const 
*serial,
+                                                    int endpoint)
+{
+       struct usb_host_interface *iface_desc;
+       struct usb_endpoint_descriptor *ep;
+       int i;
+
+       iface_desc = serial->interface->cur_altsetting;
+       for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
+               ep = &iface_desc->endpoint[i].desc;
+               if (ep->bEndpointAddress == endpoint)
+                       return ep;
+       }
+       dev_warn(&serial->interface->dev, "found no endpoint descriptor for "
+                "endpoint %x\n", endpoint);
+       return NULL;
+}
+
 static struct urb *keyspan_setup_urb (struct usb_serial *serial, int endpoint,
                                      int dir, void *ctx, char *buf, int len,
                                      void (*callback)(struct urb *))
 {
        struct urb *urb;
+       struct usb_endpoint_descriptor const *ep_desc;
+       char const *ep_type_name;
 
        if (endpoint == -1)
                return NULL;            /* endpoint not needed */
@@ -1291,11 +1311,32 @@ static struct urb *keyspan_setup_urb (struct usb_serial 
*serial, int endpoint,
                return NULL;
        }
 
-               /* Fill URB using supplied data. */
-       usb_fill_bulk_urb(urb, serial->dev,
-                     usb_sndbulkpipe(serial->dev, endpoint) | dir,
-                     buf, len, callback, ctx);
+       ep_desc = find_ep(serial, endpoint);
+       if (!ep_desc) {
+               /* leak the urb, something's wrong and the callers don't care */
+               return urb;
+       }
+       if (usb_endpoint_xfer_int(ep_desc)) {
+               ep_type_name = "INT";
+               usb_fill_int_urb(urb, serial->dev,
+                                usb_sndintpipe(serial->dev, endpoint) | dir,
+                                buf, len, callback, ctx,
+                                ep_desc->bInterval);
+       } else if (usb_endpoint_xfer_bulk(ep_desc)) {
+               ep_type_name = "BULK";
+               usb_fill_bulk_urb(urb, serial->dev,
+                                 usb_sndbulkpipe(serial->dev, endpoint) | dir,
+                                 buf, len, callback, ctx);
+       } else {
+               dev_warn(&serial->interface->dev,
+                        "unsupported endpoint type %x\n",
+                        ep_desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+               usb_free_urb(urb);
+               return NULL;
+       }
 
+       dbg("%s - using urb %p for %s endpoint %x",
+           __func__, urb, ep_type_name, endpoint);
        return urb;
 }
 
diff --git a/include/linux/netfilter_ipv4/ip_conntrack_core.h 
b/include/linux/netfilter_ipv4/ip_conntrack_core.h
index 907d4f5..e3a6df0 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack_core.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack_core.h
@@ -45,7 +45,7 @@ static inline int ip_conntrack_confirm(struct sk_buff **pskb)
        int ret = NF_ACCEPT;
 
        if (ct) {
-               if (!is_confirmed(ct))
+               if (!is_confirmed(ct) && !is_dying(ct))
                        ret = __ip_conntrack_confirm(pskb);
                ip_ct_deliver_cached_events(ct);
        }
diff --git a/include/net/inet_timewait_sock.h b/include/net/inet_timewait_sock.h
index f7be1ac..09a2532 100644
--- a/include/net/inet_timewait_sock.h
+++ b/include/net/inet_timewait_sock.h
@@ -66,7 +66,7 @@ struct inet_hashinfo;
 struct inet_timewait_death_row {
        /* Short-time timewait calendar */
        int                     twcal_hand;
-       int                     twcal_jiffie;
+       unsigned long           twcal_jiffie;
        struct timer_list       twcal_timer;
        struct hlist_head       twcal_row[INET_TWDR_RECYCLE_SLOTS];
 
diff --git a/include/net/netfilter/nf_conntrack_core.h 
b/include/net/netfilter/nf_conntrack_core.h
index 7fdc72c..85634e1 100644
--- a/include/net/netfilter/nf_conntrack_core.h
+++ b/include/net/netfilter/nf_conntrack_core.h
@@ -64,7 +64,7 @@ static inline int nf_conntrack_confirm(struct sk_buff **pskb)
        int ret = NF_ACCEPT;
 
        if (ct) {
-               if (!nf_ct_is_confirmed(ct))
+               if (!nf_ct_is_confirmed(ct) && !nf_ct_is_dying(ct))
                        ret = __nf_conntrack_confirm(pskb);
                nf_ct_deliver_cached_events(ct);
        }
diff --git a/net/core/sock.c b/net/core/sock.c
index 0ed5b4f..b69192b 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1597,7 +1597,7 @@ int compat_sock_common_getsockopt(struct socket *sock, 
int level, int optname,
 {
        struct sock *sk = sock->sk;
 
-       if (sk->sk_prot->compat_setsockopt != NULL)
+       if (sk->sk_prot->compat_getsockopt != NULL)
                return sk->sk_prot->compat_getsockopt(sk, level, optname,
                                                      optval, optlen);
        return sk->sk_prot->getsockopt(sk, level, optname, optval, optlen);
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c 
b/net/ipv4/netfilter/ip_conntrack_core.c
index 8556a4f..f8b3009 100644
--- a/net/ipv4/netfilter/ip_conntrack_core.c
+++ b/net/ipv4/netfilter/ip_conntrack_core.c
@@ -1242,7 +1242,7 @@ get_next_corpse(int (*iter)(struct ip_conntrack *i, void 
*data),
        list_for_each_entry(h, &unconfirmed, list) {
                ct = tuplehash_to_ctrack(h);
                if (iter(ct, data))
-                       goto found;
+                       set_bit(IPS_DYING_BIT, &ct->status);
        }
        write_unlock_bh(&ip_conntrack_lock);
        return NULL;
diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 
b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
index 06e4e8a..4cd76ed 100644
--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
@@ -821,8 +821,10 @@ void ip_conntrack_tcp_update(struct sk_buff *skb,
 static const u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 
1] =
 {
        [TH_SYN]                        = 1,
-       [TH_SYN|TH_ACK]                 = 1,
        [TH_SYN|TH_PUSH]                = 1,
+       [TH_SYN|TH_URG]                 = 1,
+       [TH_SYN|TH_PUSH|TH_URG]         = 1,
+       [TH_SYN|TH_ACK]                 = 1,
        [TH_SYN|TH_ACK|TH_PUSH]         = 1,
        [TH_RST]                        = 1,
        [TH_RST|TH_ACK]                 = 1,
diff --git a/net/ipv4/netfilter/nf_nat_core.c b/net/ipv4/netfilter/nf_nat_core.c
index 86a9227..8de7188 100644
--- a/net/ipv4/netfilter/nf_nat_core.c
+++ b/net/ipv4/netfilter/nf_nat_core.c
@@ -540,8 +540,7 @@ void nf_nat_protocol_unregister(struct nf_nat_protocol 
*proto)
 }
 EXPORT_SYMBOL(nf_nat_protocol_unregister);
 
-#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
-    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
 int
 nf_nat_port_range_to_nfattr(struct sk_buff *skb,
                            const struct nf_nat_range *range)
diff --git a/net/ipv4/netfilter/nf_nat_proto_gre.c 
b/net/ipv4/netfilter/nf_nat_proto_gre.c
index d3de579..e5a34c1 100644
--- a/net/ipv4/netfilter/nf_nat_proto_gre.c
+++ b/net/ipv4/netfilter/nf_nat_proto_gre.c
@@ -152,8 +152,7 @@ static struct nf_nat_protocol gre __read_mostly = {
        .manip_pkt              = gre_manip_pkt,
        .in_range               = gre_in_range,
        .unique_tuple           = gre_unique_tuple,
-#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
-    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
        .range_to_nfattr        = nf_nat_port_range_to_nfattr,
        .nfattr_to_range        = nf_nat_port_nfattr_to_range,
 #endif
diff --git a/net/ipv4/netfilter/nf_nat_proto_icmp.c 
b/net/ipv4/netfilter/nf_nat_proto_icmp.c
index dcfd772..b93c78a 100644
--- a/net/ipv4/netfilter/nf_nat_proto_icmp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_icmp.c
@@ -78,8 +78,7 @@ struct nf_nat_protocol nf_nat_protocol_icmp = {
        .manip_pkt              = icmp_manip_pkt,
        .in_range               = icmp_in_range,
        .unique_tuple           = icmp_unique_tuple,
-#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
-    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
        .range_to_nfattr        = nf_nat_port_range_to_nfattr,
        .nfattr_to_range        = nf_nat_port_nfattr_to_range,
 #endif
diff --git a/net/ipv4/netfilter/nf_nat_proto_tcp.c 
b/net/ipv4/netfilter/nf_nat_proto_tcp.c
index 7e26a7e..f6b99d6 100644
--- a/net/ipv4/netfilter/nf_nat_proto_tcp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_tcp.c
@@ -140,8 +140,7 @@ struct nf_nat_protocol nf_nat_protocol_tcp = {
        .manip_pkt              = tcp_manip_pkt,
        .in_range               = tcp_in_range,
        .unique_tuple           = tcp_unique_tuple,
-#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
-    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
        .range_to_nfattr        = nf_nat_port_range_to_nfattr,
        .nfattr_to_range        = nf_nat_port_nfattr_to_range,
 #endif
diff --git a/net/ipv4/netfilter/nf_nat_proto_udp.c 
b/net/ipv4/netfilter/nf_nat_proto_udp.c
index ab0ce4c..c00ab6e 100644
--- a/net/ipv4/netfilter/nf_nat_proto_udp.c
+++ b/net/ipv4/netfilter/nf_nat_proto_udp.c
@@ -130,8 +130,7 @@ struct nf_nat_protocol nf_nat_protocol_udp = {
        .manip_pkt              = udp_manip_pkt,
        .in_range               = udp_in_range,
        .unique_tuple           = udp_unique_tuple,
-#if defined(CONFIG_IP_NF_CONNTRACK_NETLINK) || \
-    defined(CONFIG_IP_NF_CONNTRACK_NETLINK_MODULE)
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
        .range_to_nfattr        = nf_nat_port_range_to_nfattr,
        .nfattr_to_range        = nf_nat_port_nfattr_to_range,
 #endif
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index cfff930..f8068b0 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1214,6 +1214,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head 
udptable[],
 
                if (ulen < sizeof(*uh) || pskb_trim_rcsum(skb, ulen))
                        goto short_packet;
+               uh = skb->h.uh;
 
                udp4_csum_init(skb, uh);
 
diff --git a/net/ipv6/netfilter.c b/net/ipv6/netfilter.c
index f6294e5..ca50b58 100644
--- a/net/ipv6/netfilter.c
+++ b/net/ipv6/netfilter.c
@@ -15,6 +15,7 @@ int ip6_route_me_harder(struct sk_buff *skb)
        struct dst_entry *dst;
        struct flowi fl = {
                .oif = skb->sk ? skb->sk->sk_bound_dev_if : 0,
+               .mark = skb->mark,
                .nl_u =
                { .ip6_u =
                  { .daddr = iph->daddr,
diff --git a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c 
b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
index a20615f..6155b80 100644
--- a/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
+++ b/net/ipv6/netfilter/nf_conntrack_l3proto_ipv6.c
@@ -257,6 +257,7 @@ static unsigned int ipv6_conntrack_in(unsigned int hooknum,
                }
                nf_conntrack_get(reasm->nfct);
                (*pskb)->nfct = reasm->nfct;
+               (*pskb)->nfctinfo = reasm->nfctinfo;
                return NF_ACCEPT;
        }
 
diff --git a/net/netfilter/nf_conntrack_core.c 
b/net/netfilter/nf_conntrack_core.c
index 9b02ec4..cb29ba7 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -1052,7 +1052,7 @@ get_next_corpse(int (*iter)(struct nf_conn *i, void 
*data),
        list_for_each_entry(h, &unconfirmed, list) {
                ct = nf_ct_tuplehash_to_ctrack(h);
                if (iter(ct, data))
-                       goto found;
+                       set_bit(IPS_DYING_BIT, &ct->status);
        }
        write_unlock_bh(&nf_conntrack_lock);
        return NULL;
diff --git a/net/netfilter/nf_conntrack_proto_gre.c 
b/net/netfilter/nf_conntrack_proto_gre.c
index ac193ce..5434472 100644
--- a/net/netfilter/nf_conntrack_proto_gre.c
+++ b/net/netfilter/nf_conntrack_proto_gre.c
@@ -281,8 +281,7 @@ static struct nf_conntrack_l4proto 
nf_conntrack_l4proto_gre4 = {
        .new             = gre_new,
        .destroy         = gre_destroy,
        .me              = THIS_MODULE,
-#if defined(CONFIG_NF_CONNTRACK_NETLINK) || \
-    defined(CONFIG_NF_CONNTRACK_NETLINK_MODULE)
+#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
        .tuple_to_nfattr = nf_ct_port_tuple_to_nfattr,
        .nfattr_to_tuple = nf_ct_port_nfattr_to_tuple,
 #endif
diff --git a/net/netfilter/nf_conntrack_proto_tcp.c 
b/net/netfilter/nf_conntrack_proto_tcp.c
index 626b001..693d189 100644
--- a/net/netfilter/nf_conntrack_proto_tcp.c
+++ b/net/netfilter/nf_conntrack_proto_tcp.c
@@ -778,8 +778,10 @@ EXPORT_SYMBOL_GPL(nf_conntrack_tcp_update);
 static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
 {
        [TH_SYN]                        = 1,
-       [TH_SYN|TH_ACK]                 = 1,
        [TH_SYN|TH_PUSH]                = 1,
+       [TH_SYN|TH_URG]                 = 1,
+       [TH_SYN|TH_PUSH|TH_URG]         = 1,
+       [TH_SYN|TH_ACK]                 = 1,
        [TH_SYN|TH_ACK|TH_PUSH]         = 1,
        [TH_RST]                        = 1,
        [TH_RST|TH_ACK]                 = 1,
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 24c1d29..690b173 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -397,8 +397,8 @@ static void nfulnl_timer(unsigned long data)
        if (timer_pending(&inst->timer))        /* is it always true or false 
here? */
                del_timer(&inst->timer);
        __nfulnl_send(inst);
-       instance_put(inst);
        spin_unlock_bh(&inst->lock);
+       instance_put(inst);
 }
 
 /* This is an inline function, we don't really care about a long
@@ -491,7 +491,7 @@ __build_packet_message(struct nfulnl_instance *inst,
                         * for physical device (when called from ipv4) */
                        NFA_PUT(inst->skb, NFULA_IFINDEX_OUTDEV,
                                sizeof(tmp_uint), &tmp_uint);
-                       if (skb->nf_bridge) {
+                       if (skb->nf_bridge && skb->nf_bridge->physoutdev) {
                                tmp_uint = 
                                    htonl(skb->nf_bridge->physoutdev->ifindex);
                                NFA_PUT(inst->skb, NFULA_IFINDEX_PHYSOUTDEV,
@@ -564,6 +564,7 @@ __build_packet_message(struct nfulnl_instance *inst,
        }
                
        nlh->nlmsg_len = inst->skb->tail - old_tail;
+       inst->lastnlh = nlh;
        return 0;
 
 nlmsg_failure:
@@ -619,7 +620,7 @@ nfulnl_log_packet(unsigned int pf,
 
        plen = 0;
        if (prefix)
-               plen = strlen(prefix);
+               plen = strlen(prefix) + 1;
 
        /* all macros expand to constant values at compile time */
        /* FIXME: do we want to make the size calculation conditional based on
@@ -720,15 +721,16 @@ nfulnl_log_packet(unsigned int pf,
                inst->timer.expires = jiffies + (inst->flushtimeout*HZ/100);
                add_timer(&inst->timer);
        }
-       spin_unlock_bh(&inst->lock);
 
+unlock_and_release:
+       spin_unlock_bh(&inst->lock);
+       instance_put(inst);
        return;
 
 alloc_failure:
-       spin_unlock_bh(&inst->lock);
-       instance_put(inst);
        UDEBUG("error allocating skb\n");
        /* FIXME: statistics */
+       goto unlock_and_release;
 }
 
 static int
@@ -865,6 +867,9 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
                        ret = -EINVAL;
                        break;
                }
+
+               if (!inst)
+                       goto out;
        } else {
                if (!inst) {
                        UDEBUG("no config command, and no instance for "
@@ -918,6 +923,7 @@ nfulnl_recv_config(struct sock *ctnl, struct sk_buff *skb,
 
 out_put:
        instance_put(inst);
+out:
        return ret;
 }
 
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to