OSDN Git Service

Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
authorDavid S. Miller <davem@davemloft.net>
Wed, 3 Jun 2009 09:43:41 +0000 (02:43 -0700)
committerDavid S. Miller <davem@davemloft.net>
Wed, 3 Jun 2009 09:43:41 +0000 (02:43 -0700)
Conflicts:
drivers/net/forcedeth.c

30 files changed:
MAINTAINERS
drivers/net/3c509.c
drivers/net/Makefile
drivers/net/atl1e/atl1e_main.c
drivers/net/atlx/atl1.c
drivers/net/atlx/atlx.h
drivers/net/bfin_mac.c
drivers/net/cxgb3/adapter.h
drivers/net/cxgb3/cxgb3_main.c
drivers/net/cxgb3/sge.c
drivers/net/cxgb3/t3_hw.c
drivers/net/e1000/e1000_main.c
drivers/net/forcedeth.c
drivers/net/gianfar.h
drivers/net/mac8390.c
drivers/net/mlx4/en_tx.c
drivers/net/r8169.c
drivers/net/wireless/Kconfig
drivers/net/wireless/at76c50x-usb.c
drivers/net/wireless/rtl818x/rtl8187_dev.c
firmware/cis/.gitignore [new file with mode: 0644]
include/linux/netfilter/nf_conntrack_tcp.h
net/bluetooth/hci_sysfs.c
net/ipv4/tcp_vegas.c
net/netfilter/nf_conntrack_proto_dccp.c
net/netfilter/nf_conntrack_proto_tcp.c
net/netfilter/nfnetlink_log.c
net/netfilter/xt_hashlimit.c
net/sched/cls_api.c
net/sched/cls_cgroup.c

index 77f277e..e18baa4 100644 (file)
@@ -1545,6 +1545,13 @@ W:       http://www.fi.muni.cz/~kas/cosa/
 S:     Maintained
 F:     drivers/net/wan/cosa*
 
+CPMAC ETHERNET DRIVER
+P:     Florian Fainelli
+M:     florian@openwrt.org
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     drivers/net/cpmac.c
+
 CPU FREQUENCY DRIVERS
 P:     Dave Jones
 M:     davej@redhat.com
index 8d9aa49..d2137ef 100644 (file)
@@ -480,9 +480,13 @@ static int pnp_registered;
 
 #ifdef CONFIG_EISA
 static struct eisa_device_id el3_eisa_ids[] = {
+               { "TCM5090" },
+               { "TCM5091" },
                { "TCM5092" },
                { "TCM5093" },
+               { "TCM5094" },
                { "TCM5095" },
+               { "TCM5098" },
                { "" }
 };
 MODULE_DEVICE_TABLE(eisa, el3_eisa_ids);
index f07a1e9..774c2b4 100644 (file)
@@ -105,7 +105,7 @@ obj-$(CONFIG_HAMACHI) += hamachi.o
 obj-$(CONFIG_NET) += Space.o loopback.o
 obj-$(CONFIG_SEEQ8005) += seeq8005.o
 obj-$(CONFIG_NET_SB1000) += sb1000.o
-obj-$(CONFIG_MAC8390) += mac8390.o 8390.o
+obj-$(CONFIG_MAC8390) += mac8390.o
 obj-$(CONFIG_APNE) += apne.o 8390.o
 obj-$(CONFIG_PCMCIA_PCNET) += 8390.o
 obj-$(CONFIG_HP100) += hp100.o
index a01383d..e1ae10c 100644 (file)
@@ -37,6 +37,7 @@ char atl1e_driver_version[] = DRV_VERSION;
  */
 static struct pci_device_id atl1e_pci_tbl[] = {
        {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, PCI_DEVICE_ID_ATTANSIC_L1E)},
+       {PCI_DEVICE(PCI_VENDOR_ID_ATTANSIC, 0x1066)},
        /* required last entry */
        { 0 }
 };
index fccfbf2..560f387 100644 (file)
 
 #include "atl1.h"
 
+#define ATLX_DRIVER_VERSION "2.1.3"
+MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
+       Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(ATLX_DRIVER_VERSION);
+
 /* Temporary hack for merging atl1 and atl2 */
 #include "atlx.c"
 
index 297a03d..14054b7 100644 (file)
 #include <linux/module.h>
 #include <linux/types.h>
 
-#define ATLX_DRIVER_VERSION "2.1.3"
-MODULE_AUTHOR("Xiong Huang <xiong.huang@atheros.com>, \
-       Chris Snook <csnook@redhat.com>, Jay Cliburn <jcliburn@gmail.com>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION(ATLX_DRIVER_VERSION);
-
 #define ATLX_ERR_PHY                   2
 #define ATLX_ERR_PHY_SPEED             7
 #define ATLX_ERR_PHY_RES               8
index 955a469..c15fc28 100644 (file)
@@ -927,22 +927,7 @@ static int bfin_mac_open(struct net_device *dev)
        return 0;
 }
 
-static const struct net_device_ops bfin_mac_netdev_ops = {
-       .ndo_open               = bfin_mac_open,
-       .ndo_stop               = bfin_mac_close,
-       .ndo_start_xmit         = bfin_mac_hard_start_xmit,
-       .ndo_set_mac_address    = bfin_mac_set_mac_address,
-       .ndo_tx_timeout         = bfin_mac_timeout,
-       .ndo_set_multicast_list = bfin_mac_set_multicast_list,
-       .ndo_validate_addr      = eth_validate_addr,
-       .ndo_change_mtu         = eth_change_mtu,
-#ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = bfin_mac_poll,
-#endif
-};
-
 /*
- *
  * this makes the board clean up everything that it can
  * and not talk to the outside world.   Caused by
  * an 'ifconfig ethX down'
@@ -967,6 +952,20 @@ static int bfin_mac_close(struct net_device *dev)
        return 0;
 }
 
+static const struct net_device_ops bfin_mac_netdev_ops = {
+       .ndo_open               = bfin_mac_open,
+       .ndo_stop               = bfin_mac_close,
+       .ndo_start_xmit         = bfin_mac_hard_start_xmit,
+       .ndo_set_mac_address    = bfin_mac_set_mac_address,
+       .ndo_tx_timeout         = bfin_mac_timeout,
+       .ndo_set_multicast_list = bfin_mac_set_multicast_list,
+       .ndo_validate_addr      = eth_validate_addr,
+       .ndo_change_mtu         = eth_change_mtu,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+       .ndo_poll_controller    = bfin_mac_poll,
+#endif
+};
+
 static int __devinit bfin_mac_probe(struct platform_device *pdev)
 {
        struct net_device *ndev;
index 322434a..e48e508 100644 (file)
@@ -85,8 +85,8 @@ struct fl_pg_chunk {
        struct page *page;
        void *va;
        unsigned int offset;
-       u64 *p_cnt;
-       DECLARE_PCI_UNMAP_ADDR(mapping);
+       unsigned long *p_cnt;
+       dma_addr_t mapping;
 };
 
 struct rx_desc;
index 4bc2656..aef3ab2 100644 (file)
@@ -2453,14 +2453,16 @@ static void check_link_status(struct adapter *adapter)
        for_each_port(adapter, i) {
                struct net_device *dev = adapter->port[i];
                struct port_info *p = netdev_priv(dev);
+               int link_fault;
 
                spin_lock_irq(&adapter->work_lock);
-               if (p->link_fault) {
+               link_fault = p->link_fault;
+               spin_unlock_irq(&adapter->work_lock);
+
+               if (link_fault) {
                        t3_link_fault(adapter, i);
-                       spin_unlock_irq(&adapter->work_lock);
                        continue;
                }
-               spin_unlock_irq(&adapter->work_lock);
 
                if (!(p->phy.caps & SUPPORTED_IRQ) && netif_running(dev)) {
                        t3_xgm_intr_disable(adapter, i);
index 0b97882..29c79eb 100644 (file)
@@ -355,7 +355,7 @@ static void clear_rx_desc(struct pci_dev *pdev, const struct sge_fl *q,
                (*d->pg_chunk.p_cnt)--;
                if (!*d->pg_chunk.p_cnt)
                        pci_unmap_page(pdev,
-                                      pci_unmap_addr(&d->pg_chunk, mapping),
+                                      d->pg_chunk.mapping,
                                       q->alloc_size, PCI_DMA_FROMDEVICE);
 
                put_page(d->pg_chunk.page);
@@ -454,7 +454,7 @@ static int alloc_pg_chunk(struct adapter *adapter, struct sge_fl *q,
                q->pg_chunk.offset = 0;
                mapping = pci_map_page(adapter->pdev, q->pg_chunk.page,
                                       0, q->alloc_size, PCI_DMA_FROMDEVICE);
-               pci_unmap_addr_set(&q->pg_chunk, mapping, mapping);
+               q->pg_chunk.mapping = mapping;
        }
        sd->pg_chunk = q->pg_chunk;
 
@@ -511,8 +511,7 @@ static int refill_fl(struct adapter *adap, struct sge_fl *q, int n, gfp_t gfp)
 nomem:                         q->alloc_failed++;
                                break;
                        }
-                       mapping = pci_unmap_addr(&sd->pg_chunk, mapping) +
-                                                sd->pg_chunk.offset;
+                       mapping = sd->pg_chunk.mapping + sd->pg_chunk.offset;
                        pci_unmap_addr_set(sd, dma_addr, mapping);
 
                        add_one_rx_chunk(mapping, d, q->gen);
@@ -882,7 +881,7 @@ recycle:
        (*sd->pg_chunk.p_cnt)--;
        if (!*sd->pg_chunk.p_cnt)
                pci_unmap_page(adap->pdev,
-                              pci_unmap_addr(&sd->pg_chunk, mapping),
+                              sd->pg_chunk.mapping,
                               fl->alloc_size,
                               PCI_DMA_FROMDEVICE);
        if (!skb) {
@@ -2091,7 +2090,7 @@ static void lro_add_page(struct adapter *adap, struct sge_qset *qs,
        (*sd->pg_chunk.p_cnt)--;
        if (!*sd->pg_chunk.p_cnt)
                pci_unmap_page(adap->pdev,
-                              pci_unmap_addr(&sd->pg_chunk, mapping),
+                              sd->pg_chunk.mapping,
                               fl->alloc_size,
                               PCI_DMA_FROMDEVICE);
 
index 6a45447..870d449 100644 (file)
@@ -1288,6 +1288,11 @@ void t3_link_fault(struct adapter *adapter, int port_id)
                                 A_XGM_INT_STATUS + mac->offset);
        link_fault &= F_LINKFAULTCHANGE;
 
+       link_ok = lc->link_ok;
+       speed = lc->speed;
+       duplex = lc->duplex;
+       fc = lc->fc;
+
        phy->ops->get_link_status(phy, &link_ok, &speed, &duplex, &fc);
 
        if (link_fault) {
index 74667e5..05e87a5 100644 (file)
@@ -4035,8 +4035,9 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                                 PCI_DMA_FROMDEVICE);
 
                length = le16_to_cpu(rx_desc->length);
-
-               if (unlikely(!(status & E1000_RXD_STAT_EOP))) {
+               /* !EOP means multiple descriptors were used to store a single
+                * packet, also make sure the frame isn't just CRC only */
+               if (unlikely(!(status & E1000_RXD_STAT_EOP) || (length <= 4))) {
                        /* All receives must fit into a single buffer */
                        E1000_DBG("%s: Receive packet consumed multiple"
                                  " buffers\n", netdev->name);
index d0b1d9f..1dce555 100644 (file)
@@ -898,6 +898,12 @@ enum {
 };
 static int phy_cross = NV_CROSSOVER_DETECTION_DISABLED;
 
+/*
+ * Power down phy when interface is down (persists through reboot;
+ * older Linux and other OSes may not power it up again)
+ */
+static int phy_power_down = 0;
+
 static inline struct fe_priv *get_nvpriv(struct net_device *dev)
 {
        return netdev_priv(dev);
@@ -1503,7 +1509,10 @@ static int phy_init(struct net_device *dev)
 
        /* restart auto negotiation, power down phy */
        mii_control = mii_rw(dev, np->phyaddr, MII_BMCR, MII_READ);
-       mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE | BMCR_PDOWN);
+       mii_control |= (BMCR_ANRESTART | BMCR_ANENABLE);
+       if (phy_power_down) {
+               mii_control |= BMCR_PDOWN;
+       }
        if (mii_rw(dev, np->phyaddr, MII_BMCR, mii_control)) {
                return PHY_ERROR;
        }
@@ -5534,7 +5543,7 @@ static int nv_close(struct net_device *dev)
 
        nv_drain_rxtx(dev);
 
-       if (np->wolenabled) {
+       if (np->wolenabled || !phy_power_down) {
                nv_txrx_gate(dev, false);
                writel(NVREG_PFF_ALWAYS|NVREG_PFF_MYADDR, base + NvRegPacketFilterFlags);
                nv_start_rx(dev);
@@ -6390,6 +6399,8 @@ module_param(dma_64bit, int, 0);
 MODULE_PARM_DESC(dma_64bit, "High DMA is enabled by setting to 1 and disabled by setting to 0.");
 module_param(phy_cross, int, 0);
 MODULE_PARM_DESC(phy_cross, "Phy crossover detection for Realtek 8201 phy is enabled by setting to 1 and disabled by setting to 0.");
+module_param(phy_power_down, int, 0);
+MODULE_PARM_DESC(phy_power_down, "Power down phy and disable link when interface is down (1), or leave phy powered up (0).");
 
 MODULE_AUTHOR("Manfred Spraul <manfred@colorfullife.com>");
 MODULE_DESCRIPTION("Reverse Engineered nForce ethernet driver");
index 91317bc..2cd9433 100644 (file)
@@ -259,7 +259,7 @@ extern const char gfar_driver_version[];
 (IEVENT_RXC | IEVENT_BSY | IEVENT_EBERR | IEVENT_MSRO | \
  IEVENT_BABT | IEVENT_TXC | IEVENT_TXE | IEVENT_LC \
  | IEVENT_CRL | IEVENT_XFUN | IEVENT_DPE | IEVENT_PERR \
- | IEVENT_MAG)
+ | IEVENT_MAG | IEVENT_BABR)
 
 #define IMASK_INIT_CLEAR       0x00000000
 #define IMASK_BABR              0x80000000
index 0585df1..f8fa0c3 100644 (file)
@@ -304,7 +304,7 @@ struct net_device * __init mac8390_probe(int unit)
        if (!MACH_IS_MAC)
                return ERR_PTR(-ENODEV);
 
-       dev = alloc_ei_netdev();
+       dev = ____alloc_ei_netdev(0);
        if (!dev)
                return ERR_PTR(-ENOMEM);
 
@@ -481,15 +481,15 @@ void cleanup_module(void)
 static const struct net_device_ops mac8390_netdev_ops = {
        .ndo_open               = mac8390_open,
        .ndo_stop               = mac8390_close,
-       .ndo_start_xmit         = ei_start_xmit,
-       .ndo_tx_timeout         = ei_tx_timeout,
-       .ndo_get_stats          = ei_get_stats,
-       .ndo_set_multicast_list = ei_set_multicast_list,
+       .ndo_start_xmit         = __ei_start_xmit,
+       .ndo_tx_timeout         = __ei_tx_timeout,
+       .ndo_get_stats          = __ei_get_stats,
+       .ndo_set_multicast_list = __ei_set_multicast_list,
        .ndo_validate_addr      = eth_validate_addr,
        .ndo_set_mac_address    = eth_mac_addr,
        .ndo_change_mtu         = eth_change_mtu,
 #ifdef CONFIG_NET_POLL_CONTROLLER
-       .ndo_poll_controller    = ei_poll,
+       .ndo_poll_controller    = __ei_poll,
 #endif
 };
 
index 3719d1a..5dc7466 100644 (file)
@@ -388,7 +388,7 @@ void mlx4_en_poll_tx_cq(unsigned long data)
 
        INC_PERF_COUNTER(priv->pstats.tx_poll);
 
-       if (!spin_trylock(&ring->comp_lock)) {
+       if (!spin_trylock_irq(&ring->comp_lock)) {
                mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT);
                return;
        }
@@ -401,7 +401,7 @@ void mlx4_en_poll_tx_cq(unsigned long data)
        if (inflight && priv->port_up)
                mod_timer(&cq->timer, jiffies + MLX4_EN_TX_POLL_TIMEOUT);
 
-       spin_unlock(&ring->comp_lock);
+       spin_unlock_irq(&ring->comp_lock);
 }
 
 static struct mlx4_en_tx_desc *mlx4_en_bounce_to_desc(struct mlx4_en_priv *priv,
@@ -444,9 +444,9 @@ static inline void mlx4_en_xmit_poll(struct mlx4_en_priv *priv, int tx_ind)
 
        /* Poll the CQ every mlx4_en_TX_MODER_POLL packets */
        if ((++ring->poll_cnt & (MLX4_EN_TX_POLL_MODER - 1)) == 0)
-               if (spin_trylock(&ring->comp_lock)) {
+               if (spin_trylock_irq(&ring->comp_lock)) {
                        mlx4_en_process_tx_cq(priv->dev, cq);
-                       spin_unlock(&ring->comp_lock);
+                       spin_unlock_irq(&ring->comp_lock);
                }
 }
 
index 7fa88d2..e94316b 100644 (file)
@@ -3561,54 +3561,64 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance)
        int handled = 0;
        int status;
 
+       /* loop handling interrupts until we have no new ones or
+        * we hit a invalid/hotplug case.
+        */
        status = RTL_R16(IntrStatus);
+       while (status && status != 0xffff) {
+               handled = 1;
 
-       /* hotplug/major error/no more work/shared irq */
-       if ((status == 0xffff) || !status)
-               goto out;
-
-       handled = 1;
+               /* Handle all of the error cases first. These will reset
+                * the chip, so just exit the loop.
+                */
+               if (unlikely(!netif_running(dev))) {
+                       rtl8169_asic_down(ioaddr);
+                       break;
+               }
 
-       if (unlikely(!netif_running(dev))) {
-               rtl8169_asic_down(ioaddr);
-               goto out;
-       }
+               /* Work around for rx fifo overflow */
+               if (unlikely(status & RxFIFOOver) &&
+               (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
+                       netif_stop_queue(dev);
+                       rtl8169_tx_timeout(dev);
+                       break;
+               }
 
-       status &= tp->intr_mask;
-       RTL_W16(IntrStatus,
-               (status & RxFIFOOver) ? (status | RxOverflow) : status);
+               if (unlikely(status & SYSErr)) {
+                       rtl8169_pcierr_interrupt(dev);
+                       break;
+               }
 
-       if (!(status & tp->intr_event))
-               goto out;
+               if (status & LinkChg)
+                       rtl8169_check_link_status(dev, tp, ioaddr);
 
-       /* Work around for rx fifo overflow */
-       if (unlikely(status & RxFIFOOver) &&
-           (tp->mac_version == RTL_GIGA_MAC_VER_11)) {
-               netif_stop_queue(dev);
-               rtl8169_tx_timeout(dev);
-               goto out;
-       }
+               /* We need to see the lastest version of tp->intr_mask to
+                * avoid ignoring an MSI interrupt and having to wait for
+                * another event which may never come.
+                */
+               smp_rmb();
+               if (status & tp->intr_mask & tp->napi_event) {
+                       RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
+                       tp->intr_mask = ~tp->napi_event;
+
+                       if (likely(napi_schedule_prep(&tp->napi)))
+                               __napi_schedule(&tp->napi);
+                       else if (netif_msg_intr(tp)) {
+                               printk(KERN_INFO "%s: interrupt %04x in poll\n",
+                               dev->name, status);
+                       }
+               }
 
-       if (unlikely(status & SYSErr)) {
-               rtl8169_pcierr_interrupt(dev);
-               goto out;
+               /* We only get a new MSI interrupt when all active irq
+                * sources on the chip have been acknowledged. So, ack
+                * everything we've seen and check if new sources have become
+                * active to avoid blocking all interrupts from the chip.
+                */
+               RTL_W16(IntrStatus,
+                       (status & RxFIFOOver) ? (status | RxOverflow) : status);
+               status = RTL_R16(IntrStatus);
        }
 
-       if (status & LinkChg)
-               rtl8169_check_link_status(dev, tp, ioaddr);
-
-       if (status & tp->napi_event) {
-               RTL_W16(IntrMask, tp->intr_event & ~tp->napi_event);
-               tp->intr_mask = ~tp->napi_event;
-
-               if (likely(napi_schedule_prep(&tp->napi)))
-                       __napi_schedule(&tp->napi);
-               else if (netif_msg_intr(tp)) {
-                       printk(KERN_INFO "%s: interrupt %04x in poll\n",
-                              dev->name, status);
-               }
-       }
-out:
        return IRQ_RETVAL(handled);
 }
 
@@ -3624,13 +3634,15 @@ static int rtl8169_poll(struct napi_struct *napi, int budget)
 
        if (work_done < budget) {
                napi_complete(napi);
-               tp->intr_mask = 0xffff;
-               /*
-                * 20040426: the barrier is not strictly required but the
-                * behavior of the irq handler could be less predictable
-                * without it. Btw, the lack of flush for the posted pci
-                * write is safe - FR
+
+               /* We need for force the visibility of tp->intr_mask
+                * for other CPUs, as we can loose an MSI interrupt
+                * and potentially wait for a retransmit timeout if we don't.
+                * The posted write to IntrMask is safe, as it will
+                * eventually make it to the chip and we won't loose anything
+                * until it does.
                 */
+               tp->intr_mask = 0xffff;
                smp_wmb();
                RTL_W16(IntrMask, tp->intr_event);
        }
index a67d292..8673241 100644 (file)
@@ -431,6 +431,7 @@ config RTL8187
          ASUS P5B Deluxe
          Toshiba Satellite Pro series of laptops
          Asus Wireless Link
+         Linksys WUSB54GC-EU
 
          Thanks to Realtek for their support!
 
index cea7f14..4efbdbe 100644 (file)
@@ -1873,18 +1873,18 @@ static void at76_dwork_hw_scan(struct work_struct *work)
        if (ret != CMD_STATUS_COMPLETE) {
                queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan,
                                   SCAN_POLL_INTERVAL);
-               goto exit;
+               mutex_unlock(&priv->mtx);
+               return;
        }
 
-       ieee80211_scan_completed(priv->hw, false);
-
        if (is_valid_ether_addr(priv->bssid))
                at76_join(priv);
 
-       ieee80211_wake_queues(priv->hw);
-
-exit:
        mutex_unlock(&priv->mtx);
+
+       ieee80211_scan_completed(priv->hw, false);
+
+       ieee80211_wake_queues(priv->hw);
 }
 
 static int at76_hw_scan(struct ieee80211_hw *hw,
index 3f22cc0..294250e 100644 (file)
@@ -74,6 +74,8 @@ static struct usb_device_id rtl8187_table[] __devinitdata = {
        {USB_DEVICE(0x18E8, 0x6232), .driver_info = DEVICE_RTL8187},
        /* AirLive */
        {USB_DEVICE(0x1b75, 0x8187), .driver_info = DEVICE_RTL8187},
+       /* Linksys */
+       {USB_DEVICE(0x1737, 0x0073), .driver_info = DEVICE_RTL8187B},
        {}
 };
 
diff --git a/firmware/cis/.gitignore b/firmware/cis/.gitignore
new file mode 100644 (file)
index 0000000..1de3984
--- /dev/null
@@ -0,0 +1 @@
+*.cis
index 3066789..b2f384d 100644 (file)
@@ -35,6 +35,9 @@ enum tcp_conntrack {
 /* Has unacknowledged data */
 #define IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED     0x10
 
+/* The field td_maxack has been set */
+#define IP_CT_TCP_FLAG_MAXACK_SET              0x20
+
 struct nf_ct_tcp_flags {
        __u8 flags;
        __u8 mask;
@@ -46,6 +49,7 @@ struct ip_ct_tcp_state {
        u_int32_t       td_end;         /* max of seq + len */
        u_int32_t       td_maxend;      /* max of ack + max(win, 1) */
        u_int32_t       td_maxwin;      /* max(win) */
+       u_int32_t       td_maxack;      /* max of ack */
        u_int8_t        td_scale;       /* window scale factor */
        u_int8_t        flags;          /* per direction options */
 };
index 4cc3624..95f7a7a 100644 (file)
@@ -90,9 +90,6 @@ static void add_conn(struct work_struct *work)
        struct hci_conn *conn = container_of(work, struct hci_conn, work_add);
        struct hci_dev *hdev = conn->hdev;
 
-       /* ensure previous del is complete */
-       flush_work(&conn->work_del);
-
        dev_set_name(&conn->dev, "%s:%d", hdev->name, conn->handle);
 
        if (device_add(&conn->dev) < 0) {
@@ -118,9 +115,6 @@ static void del_conn(struct work_struct *work)
        struct hci_conn *conn = container_of(work, struct hci_conn, work_del);
        struct hci_dev *hdev = conn->hdev;
 
-       /* ensure previous add is complete */
-       flush_work(&conn->work_add);
-
        if (!device_is_registered(&conn->dev))
                return;
 
index a453aac..c6743ee 100644 (file)
@@ -158,6 +158,11 @@ void tcp_vegas_cwnd_event(struct sock *sk, enum tcp_ca_event event)
 }
 EXPORT_SYMBOL_GPL(tcp_vegas_cwnd_event);
 
+static inline u32 tcp_vegas_ssthresh(struct tcp_sock *tp)
+{
+       return  min(tp->snd_ssthresh, tp->snd_cwnd-1);
+}
+
 static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
 {
        struct tcp_sock *tp = tcp_sk(sk);
@@ -221,11 +226,10 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
                         */
                        diff = tp->snd_cwnd * (rtt-vegas->baseRTT) / vegas->baseRTT;
 
-                       if (diff > gamma && tp->snd_ssthresh > 2 ) {
+                       if (diff > gamma && tp->snd_cwnd <= tp->snd_ssthresh) {
                                /* Going too fast. Time to slow down
                                 * and switch to congestion avoidance.
                                 */
-                               tp->snd_ssthresh = 2;
 
                                /* Set cwnd to match the actual rate
                                 * exactly:
@@ -235,6 +239,7 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
                                 * utilization.
                                 */
                                tp->snd_cwnd = min(tp->snd_cwnd, (u32)target_cwnd+1);
+                               tp->snd_ssthresh = tcp_vegas_ssthresh(tp);
 
                        } else if (tp->snd_cwnd <= tp->snd_ssthresh) {
                                /* Slow start.  */
@@ -250,6 +255,8 @@ static void tcp_vegas_cong_avoid(struct sock *sk, u32 ack, u32 in_flight)
                                         * we slow down.
                                         */
                                        tp->snd_cwnd--;
+                                       tp->snd_ssthresh
+                                               = tcp_vegas_ssthresh(tp);
                                } else if (diff < alpha) {
                                        /* We don't have enough extra packets
                                         * in the network, so speed up.
index 8e757dd..aee0d6b 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/netfilter/nfnetlink_conntrack.h>
 #include <net/netfilter/nf_conntrack.h>
 #include <net/netfilter/nf_conntrack_l4proto.h>
+#include <net/netfilter/nf_conntrack_ecache.h>
 #include <net/netfilter/nf_log.h>
 
 static DEFINE_RWLOCK(dccp_lock);
@@ -553,6 +554,9 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
        ct->proto.dccp.state = new_state;
        write_unlock_bh(&dccp_lock);
 
+       if (new_state != old_state)
+               nf_conntrack_event_cache(IPCT_PROTOINFO, ct);
+
        dn = dccp_pernet(net);
        nf_ct_refresh_acct(ct, ctinfo, skb, dn->dccp_timeout[new_state]);
 
index b5ccf2b..97a6e93 100644 (file)
@@ -634,6 +634,14 @@ static bool tcp_in_window(const struct nf_conn *ct,
                        sender->td_end = end;
                        sender->flags |= IP_CT_TCP_FLAG_DATA_UNACKNOWLEDGED;
                }
+               if (tcph->ack) {
+                       if (!(sender->flags & IP_CT_TCP_FLAG_MAXACK_SET)) {
+                               sender->td_maxack = ack;
+                               sender->flags |= IP_CT_TCP_FLAG_MAXACK_SET;
+                       } else if (after(ack, sender->td_maxack))
+                               sender->td_maxack = ack;
+               }
+
                /*
                 * Update receiver data.
                 */
@@ -919,6 +927,16 @@ static int tcp_packet(struct nf_conn *ct,
                return -NF_ACCEPT;
        case TCP_CONNTRACK_CLOSE:
                if (index == TCP_RST_SET
+                   && (ct->proto.tcp.seen[!dir].flags & IP_CT_TCP_FLAG_MAXACK_SET)
+                   && before(ntohl(th->seq), ct->proto.tcp.seen[!dir].td_maxack)) {
+                       /* Invalid RST  */
+                       write_unlock_bh(&tcp_lock);
+                       if (LOG_INVALID(net, IPPROTO_TCP))
+                               nf_log_packet(pf, 0, skb, NULL, NULL, NULL,
+                                         "nf_ct_tcp: invalid RST ");
+                       return -NF_ACCEPT;
+               }
+               if (index == TCP_RST_SET
                    && ((test_bit(IPS_SEEN_REPLY_BIT, &ct->status)
                         && ct->proto.tcp.last_index == TCP_SYN_SET)
                        || (!test_bit(IPS_ASSURED_BIT, &ct->status)
index fd326ac..66a6dd5 100644 (file)
@@ -581,6 +581,12 @@ nfulnl_log_packet(u_int8_t pf,
                + nla_total_size(sizeof(struct nfulnl_msg_packet_hw))
                + nla_total_size(sizeof(struct nfulnl_msg_packet_timestamp));
 
+       if (in && skb_mac_header_was_set(skb)) {
+               size +=   nla_total_size(skb->dev->hard_header_len)
+                       + nla_total_size(sizeof(u_int16_t))     /* hwtype */
+                       + nla_total_size(sizeof(u_int16_t));    /* hwlen */
+       }
+
        spin_lock_bh(&inst->lock);
 
        if (inst->flags & NFULNL_CFG_F_SEQ)
index a5b5369..219dcdb 100644 (file)
@@ -926,7 +926,7 @@ static int dl_seq_show(struct seq_file *s, void *v)
        if (!hlist_empty(&htable->hash[*bucket])) {
                hlist_for_each_entry(ent, pos, &htable->hash[*bucket], node)
                        if (dl_seq_real_show(ent, htable->family, s))
-                               return 1;
+                               return -1;
        }
        return 0;
 }
index 0759f32..09cdcdf 100644 (file)
@@ -135,6 +135,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
        unsigned long cl;
        unsigned long fh;
        int err;
+       int tp_created = 0;
 
        if (net != &init_net)
                return -EINVAL;
@@ -266,10 +267,7 @@ replay:
                        goto errout;
                }
 
-               spin_lock_bh(root_lock);
-               tp->next = *back;
-               *back = tp;
-               spin_unlock_bh(root_lock);
+               tp_created = 1;
 
        } else if (tca[TCA_KIND] && nla_strcmp(tca[TCA_KIND], tp->ops->kind))
                goto errout;
@@ -296,8 +294,11 @@ replay:
                switch (n->nlmsg_type) {
                case RTM_NEWTFILTER:
                        err = -EEXIST;
-                       if (n->nlmsg_flags & NLM_F_EXCL)
+                       if (n->nlmsg_flags & NLM_F_EXCL) {
+                               if (tp_created)
+                                       tcf_destroy(tp);
                                goto errout;
+                       }
                        break;
                case RTM_DELTFILTER:
                        err = tp->ops->delete(tp, fh);
@@ -314,8 +315,18 @@ replay:
        }
 
        err = tp->ops->change(tp, cl, t->tcm_handle, tca, &fh);
-       if (err == 0)
+       if (err == 0) {
+               if (tp_created) {
+                       spin_lock_bh(root_lock);
+                       tp->next = *back;
+                       *back = tp;
+                       spin_unlock_bh(root_lock);
+               }
                tfilter_notify(skb, n, tp, fh, RTM_NEWTFILTER);
+       } else {
+               if (tp_created)
+                       tcf_destroy(tp);
+       }
 
 errout:
        if (cl)
index 1ab4542..0f815cc 100644 (file)
@@ -98,8 +98,7 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp,
                               struct tcf_result *res)
 {
        struct cls_cgroup_head *head = tp->root;
-       struct cgroup_cls_state *cs;
-       int ret = 0;
+       u32 classid;
 
        /*
         * Due to the nature of the classifier it is required to ignore all
@@ -115,17 +114,18 @@ static int cls_cgroup_classify(struct sk_buff *skb, struct tcf_proto *tp,
                return -1;
 
        rcu_read_lock();
-       cs = task_cls_state(current);
-       if (cs->classid && tcf_em_tree_match(skb, &head->ematches, NULL)) {
-               res->classid = cs->classid;
-               res->class = 0;
-               ret = tcf_exts_exec(skb, &head->exts, res);
-       } else
-               ret = -1;
-
+       classid = task_cls_state(current)->classid;
        rcu_read_unlock();
 
-       return ret;
+       if (!classid)
+               return -1;
+
+       if (!tcf_em_tree_match(skb, &head->ematches, NULL))
+               return -1;
+
+       res->classid = classid;
+       res->class = 0;
+       return tcf_exts_exec(skb, &head->exts, res);
 }
 
 static unsigned long cls_cgroup_get(struct tcf_proto *tp, u32 handle)