Explorar o código

Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6: (34 commits)
  net: Add support for SMSC LAN9530, LAN9730 and LAN89530
  mlx4_en: Restoring RX buffer pointer in case of failure
  mlx4: Sensing link type at device initialization
  ipv4: Fix "Set rt->rt_iif more sanely on output routes."
  MAINTAINERS: add entry for Xen network backend
  be2net: Fix suspend/resume operation
  be2net: Rename some struct members for clarity
  pppoe: drop PPPOX_ZOMBIEs in pppoe_flush_dev
  dsa/mv88e6131: add support for mv88e6085 switch
  ipv6: Enable RFS sk_rxhash tracking for ipv6 sockets (v2)
  be2net: Fix a potential crash during shutdown.
  bna: Fix for handling firmware heartbeat failure
  can: mcp251x: Allow pass IRQ flags through platform data.
  smsc911x: fix mac_lock acquision before calling smsc911x_mac_read
  iwlwifi: accept EEPROM version 0x423 for iwl6000
  rt2x00: fix cancelling uninitialized work
  rtlwifi: Fix some warnings/bugs
  p54usb: IDs for two new devices
  wl12xx: fix potential buffer overflow in testmode nvs push
  zd1211rw: reset rx idle timer from tasklet
  ...
Linus Torvalds %!s(int64=14) %!d(string=hai) anos
pai
achega
c44eaf41a5
Modificáronse 54 ficheiros con 301 adicións e 164 borrados
  1. 7 0
      MAINTAINERS
  2. 2 2
      drivers/net/benet/be.h
  3. 11 8
      drivers/net/benet/be_main.c
  4. 3 7
      drivers/net/bna/bfa_ioc.c
  5. 2 1
      drivers/net/can/mcp251x.c
  6. 4 0
      drivers/net/mlx4/en_rx.c
  7. 5 0
      drivers/net/mlx4/main.c
  8. 2 0
      drivers/net/mlx4/mlx4.h
  9. 2 2
      drivers/net/mlx4/sense.c
  10. 1 1
      drivers/net/pppoe.c
  11. 5 3
      drivers/net/smsc911x.c
  12. 15 0
      drivers/net/usb/smsc95xx.c
  13. 1 0
      drivers/net/wireless/ath/ath9k/hw.c
  14. 1 1
      drivers/net/wireless/b43/dma.c
  15. 1 1
      drivers/net/wireless/b43/dma.h
  16. 1 1
      drivers/net/wireless/iwlwifi/iwl-eeprom.h
  17. 2 0
      drivers/net/wireless/p54/p54usb.c
  18. 4 2
      drivers/net/wireless/rt2x00/rt2x00dev.c
  19. 1 1
      drivers/net/wireless/rtlwifi/efuse.c
  20. 1 1
      drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
  21. 1 1
      drivers/net/wireless/rtlwifi/usb.c
  22. 1 1
      drivers/net/wireless/wl12xx/sdio.c
  23. 1 1
      drivers/net/wireless/wl12xx/spi.c
  24. 4 1
      drivers/net/wireless/wl12xx/testmode.c
  25. 18 2
      drivers/net/wireless/zd1211rw/zd_usb.c
  26. 1 0
      drivers/net/wireless/zd1211rw/zd_usb.h
  27. 2 0
      include/linux/can/platform/mcp251x.h
  28. 2 1
      include/linux/netfilter.h
  29. 1 1
      include/linux/netfilter/ipset/ip_set.h
  30. 1 2
      include/linux/netfilter/ipset/ip_set_ahash.h
  31. 1 1
      include/net/ip_vs.h
  32. 13 2
      include/net/mac80211.h
  33. 3 2
      include/net/route.h
  34. 19 4
      net/dsa/mv88e6131.c
  35. 2 0
      net/dsa/mv88e6xxx.h
  36. 3 2
      net/ipv4/netfilter.c
  37. 6 2
      net/ipv4/route.c
  38. 1 0
      net/ipv4/xfrm4_policy.c
  39. 11 2
      net/ipv6/netfilter.c
  40. 3 1
      net/ipv6/tcp_ipv6.c
  41. 3 0
      net/ipv6/udp.c
  42. 1 1
      net/mac80211/rx.c
  43. 0 1
      net/netfilter/Kconfig
  44. 1 2
      net/netfilter/ipset/ip_set_bitmap_ip.c
  45. 1 2
      net/netfilter/ipset/ip_set_bitmap_ipmac.c
  46. 1 2
      net/netfilter/ipset/ip_set_bitmap_port.c
  47. 66 43
      net/netfilter/ipset/ip_set_core.c
  48. 23 30
      net/netfilter/ipset/ip_set_list_set.c
  49. 1 1
      net/netfilter/ipvs/ip_vs_ctl.c
  50. 1 1
      net/netfilter/nf_conntrack_h323_asn1.c
  51. 8 8
      net/netfilter/nf_conntrack_h323_main.c
  52. 1 1
      net/netfilter/xt_TCPMSS.c
  53. 28 14
      net/netfilter/xt_addrtype.c
  54. 1 1
      net/netfilter/xt_conntrack.c

+ 7 - 0
MAINTAINERS

@@ -6916,6 +6916,13 @@ T:	git git://git.kernel.org/pub/scm/linux/kernel/git/mjg59/platform-drivers-x86.
 S:	Maintained
 S:	Maintained
 F:	drivers/platform/x86
 F:	drivers/platform/x86
 
 
+XEN NETWORK BACKEND DRIVER
+M:	Ian Campbell <ian.campbell@citrix.com>
+L:	xen-devel@lists.xensource.com (moderated for non-subscribers)
+L:	netdev@vger.kernel.org
+S:	Supported
+F:	drivers/net/xen-netback/*
+
 XEN PCI SUBSYSTEM
 XEN PCI SUBSYSTEM
 M:	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 M:	Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
 L:	xen-devel@lists.xensource.com (moderated for non-subscribers)
 L:	xen-devel@lists.xensource.com (moderated for non-subscribers)

+ 2 - 2
drivers/net/benet/be.h

@@ -154,7 +154,7 @@ struct be_eq_obj {
 	u16 min_eqd;		/* in usecs */
 	u16 min_eqd;		/* in usecs */
 	u16 max_eqd;		/* in usecs */
 	u16 max_eqd;		/* in usecs */
 	u16 cur_eqd;		/* in usecs */
 	u16 cur_eqd;		/* in usecs */
-	u8  msix_vec_idx;
+	u8  eq_idx;
 
 
 	struct napi_struct napi;
 	struct napi_struct napi;
 };
 };
@@ -291,7 +291,7 @@ struct be_adapter {
 	u32 num_rx_qs;
 	u32 num_rx_qs;
 	u32 big_page_size;	/* Compounded page size shared by rx wrbs */
 	u32 big_page_size;	/* Compounded page size shared by rx wrbs */
 
 
-	u8 msix_vec_next_idx;
+	u8 eq_next_idx;
 	struct be_drv_stats drv_stats;
 	struct be_drv_stats drv_stats;
 
 
 	struct vlan_group *vlan_grp;
 	struct vlan_group *vlan_grp;

+ 11 - 8
drivers/net/benet/be_main.c

@@ -1497,7 +1497,7 @@ static int be_tx_queues_create(struct be_adapter *adapter)
 	if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd))
 	if (be_cmd_eq_create(adapter, eq, adapter->tx_eq.cur_eqd))
 		goto tx_eq_free;
 		goto tx_eq_free;
 
 
-	adapter->tx_eq.msix_vec_idx = adapter->msix_vec_next_idx++;
+	adapter->tx_eq.eq_idx = adapter->eq_next_idx++;
 
 
 
 
 	/* Alloc TX eth compl queue */
 	/* Alloc TX eth compl queue */
@@ -1590,7 +1590,7 @@ static int be_rx_queues_create(struct be_adapter *adapter)
 		if (rc)
 		if (rc)
 			goto err;
 			goto err;
 
 
-		rxo->rx_eq.msix_vec_idx = adapter->msix_vec_next_idx++;
+		rxo->rx_eq.eq_idx = adapter->eq_next_idx++;
 
 
 		/* CQ */
 		/* CQ */
 		cq = &rxo->cq;
 		cq = &rxo->cq;
@@ -1666,11 +1666,11 @@ static irqreturn_t be_intx(int irq, void *dev)
 		if (!isr)
 		if (!isr)
 			return IRQ_NONE;
 			return IRQ_NONE;
 
 
-		if ((1 << adapter->tx_eq.msix_vec_idx & isr))
+		if ((1 << adapter->tx_eq.eq_idx & isr))
 			event_handle(adapter, &adapter->tx_eq);
 			event_handle(adapter, &adapter->tx_eq);
 
 
 		for_all_rx_queues(adapter, rxo, i) {
 		for_all_rx_queues(adapter, rxo, i) {
-			if ((1 << rxo->rx_eq.msix_vec_idx & isr))
+			if ((1 << rxo->rx_eq.eq_idx & isr))
 				event_handle(adapter, &rxo->rx_eq);
 				event_handle(adapter, &rxo->rx_eq);
 		}
 		}
 	}
 	}
@@ -1951,7 +1951,7 @@ static void be_sriov_disable(struct be_adapter *adapter)
 static inline int be_msix_vec_get(struct be_adapter *adapter,
 static inline int be_msix_vec_get(struct be_adapter *adapter,
 					struct be_eq_obj *eq_obj)
 					struct be_eq_obj *eq_obj)
 {
 {
-	return adapter->msix_entries[eq_obj->msix_vec_idx].vector;
+	return adapter->msix_entries[eq_obj->eq_idx].vector;
 }
 }
 
 
 static int be_request_irq(struct be_adapter *adapter,
 static int be_request_irq(struct be_adapter *adapter,
@@ -2345,6 +2345,7 @@ static int be_clear(struct be_adapter *adapter)
 	be_mcc_queues_destroy(adapter);
 	be_mcc_queues_destroy(adapter);
 	be_rx_queues_destroy(adapter);
 	be_rx_queues_destroy(adapter);
 	be_tx_queues_destroy(adapter);
 	be_tx_queues_destroy(adapter);
+	adapter->eq_next_idx = 0;
 
 
 	if (be_physfn(adapter) && adapter->sriov_enabled)
 	if (be_physfn(adapter) && adapter->sriov_enabled)
 		for (vf = 0; vf < num_vfs; vf++)
 		for (vf = 0; vf < num_vfs; vf++)
@@ -3141,12 +3142,14 @@ static int be_resume(struct pci_dev *pdev)
 static void be_shutdown(struct pci_dev *pdev)
 static void be_shutdown(struct pci_dev *pdev)
 {
 {
 	struct be_adapter *adapter = pci_get_drvdata(pdev);
 	struct be_adapter *adapter = pci_get_drvdata(pdev);
-	struct net_device *netdev =  adapter->netdev;
 
 
-	if (netif_running(netdev))
+	if (!adapter)
+		return;
+
+	if (netif_running(adapter->netdev))
 		cancel_delayed_work_sync(&adapter->work);
 		cancel_delayed_work_sync(&adapter->work);
 
 
-	netif_device_detach(netdev);
+	netif_device_detach(adapter->netdev);
 
 
 	be_cmd_reset_function(adapter);
 	be_cmd_reset_function(adapter);
 
 

+ 3 - 7
drivers/net/bna/bfa_ioc.c

@@ -2219,13 +2219,9 @@ bfa_nw_ioc_get_mac(struct bfa_ioc *ioc)
 static void
 static void
 bfa_ioc_recover(struct bfa_ioc *ioc)
 bfa_ioc_recover(struct bfa_ioc *ioc)
 {
 {
-	u16 bdf;
-
-	bdf = (ioc->pcidev.pci_slot << 8 | ioc->pcidev.pci_func << 3 |
-					ioc->pcidev.device_id);
-
-	pr_crit("Firmware heartbeat failure at %d", bdf);
-	BUG_ON(1);
+	pr_crit("Heart Beat of IOC has failed\n");
+	bfa_ioc_stats(ioc, ioc_hbfails);
+	bfa_fsm_send_event(ioc, IOC_E_HBFAIL);
 }
 }
 
 
 static void
 static void

+ 2 - 1
drivers/net/can/mcp251x.c

@@ -931,7 +931,8 @@ static int mcp251x_open(struct net_device *net)
 	priv->tx_len = 0;
 	priv->tx_len = 0;
 
 
 	ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
 	ret = request_threaded_irq(spi->irq, NULL, mcp251x_can_ist,
-			  IRQF_TRIGGER_FALLING, DEVICE_NAME, priv);
+		  pdata->irq_flags ? pdata->irq_flags : IRQF_TRIGGER_FALLING,
+		  DEVICE_NAME, priv);
 	if (ret) {
 	if (ret) {
 		dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
 		dev_err(&spi->dev, "failed to acquire irq %d\n", spi->irq);
 		if (pdata->transceiver_enable)
 		if (pdata->transceiver_enable)

+ 4 - 0
drivers/net/mlx4/en_rx.c

@@ -345,6 +345,8 @@ int mlx4_en_activate_rx_rings(struct mlx4_en_priv *priv)
 		err = mlx4_en_init_allocator(priv, ring);
 		err = mlx4_en_init_allocator(priv, ring);
 		if (err) {
 		if (err) {
 			en_err(priv, "Failed initializing ring allocator\n");
 			en_err(priv, "Failed initializing ring allocator\n");
+			if (ring->stride <= TXBB_SIZE)
+				ring->buf -= TXBB_SIZE;
 			ring_ind--;
 			ring_ind--;
 			goto err_allocator;
 			goto err_allocator;
 		}
 		}
@@ -369,6 +371,8 @@ err_buffers:
 	ring_ind = priv->rx_ring_num - 1;
 	ring_ind = priv->rx_ring_num - 1;
 err_allocator:
 err_allocator:
 	while (ring_ind >= 0) {
 	while (ring_ind >= 0) {
+		if (priv->rx_ring[ring_ind].stride <= TXBB_SIZE)
+			priv->rx_ring[ring_ind].buf -= TXBB_SIZE;
 		mlx4_en_destroy_allocator(priv, &priv->rx_ring[ring_ind]);
 		mlx4_en_destroy_allocator(priv, &priv->rx_ring[ring_ind]);
 		ring_ind--;
 		ring_ind--;
 	}
 	}

+ 5 - 0
drivers/net/mlx4/main.c

@@ -944,6 +944,10 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
 	}
 	}
 
 
 	for (port = 1; port <= dev->caps.num_ports; port++) {
 	for (port = 1; port <= dev->caps.num_ports; port++) {
+		enum mlx4_port_type port_type = 0;
+		mlx4_SENSE_PORT(dev, port, &port_type);
+		if (port_type)
+			dev->caps.port_type[port] = port_type;
 		ib_port_default_caps = 0;
 		ib_port_default_caps = 0;
 		err = mlx4_get_port_ib_caps(dev, port, &ib_port_default_caps);
 		err = mlx4_get_port_ib_caps(dev, port, &ib_port_default_caps);
 		if (err)
 		if (err)
@@ -958,6 +962,7 @@ static int mlx4_setup_hca(struct mlx4_dev *dev)
 			goto err_mcg_table_free;
 			goto err_mcg_table_free;
 		}
 		}
 	}
 	}
+	mlx4_set_port_mask(dev);
 
 
 	return 0;
 	return 0;
 
 

+ 2 - 0
drivers/net/mlx4/mlx4.h

@@ -431,6 +431,8 @@ void mlx4_srq_event(struct mlx4_dev *dev, u32 srqn, int event_type);
 
 
 void mlx4_handle_catas_err(struct mlx4_dev *dev);
 void mlx4_handle_catas_err(struct mlx4_dev *dev);
 
 
+int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port,
+		    enum mlx4_port_type *type);
 void mlx4_do_sense_ports(struct mlx4_dev *dev,
 void mlx4_do_sense_ports(struct mlx4_dev *dev,
 			 enum mlx4_port_type *stype,
 			 enum mlx4_port_type *stype,
 			 enum mlx4_port_type *defaults);
 			 enum mlx4_port_type *defaults);

+ 2 - 2
drivers/net/mlx4/sense.c

@@ -38,8 +38,8 @@
 
 
 #include "mlx4.h"
 #include "mlx4.h"
 
 
-static int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port,
-			   enum mlx4_port_type *type)
+int mlx4_SENSE_PORT(struct mlx4_dev *dev, int port,
+		    enum mlx4_port_type *type)
 {
 {
 	u64 out_param;
 	u64 out_param;
 	int err = 0;
 	int err = 0;

+ 1 - 1
drivers/net/pppoe.c

@@ -317,7 +317,7 @@ static void pppoe_flush_dev(struct net_device *dev)
 			lock_sock(sk);
 			lock_sock(sk);
 
 
 			if (po->pppoe_dev == dev &&
 			if (po->pppoe_dev == dev &&
-			    sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND)) {
+			    sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
 				pppox_unbind_sock(sk);
 				pppox_unbind_sock(sk);
 				sk->sk_state = PPPOX_ZOMBIE;
 				sk->sk_state = PPPOX_ZOMBIE;
 				sk->sk_state_change(sk);
 				sk->sk_state_change(sk);

+ 5 - 3
drivers/net/smsc911x.c

@@ -1818,6 +1818,7 @@ static int __devinit smsc911x_init(struct net_device *dev)
 	SMSC_TRACE(PROBE, "PHY will be autodetected.");
 	SMSC_TRACE(PROBE, "PHY will be autodetected.");
 
 
 	spin_lock_init(&pdata->dev_lock);
 	spin_lock_init(&pdata->dev_lock);
+	spin_lock_init(&pdata->mac_lock);
 
 
 	if (pdata->ioaddr == 0) {
 	if (pdata->ioaddr == 0) {
 		SMSC_WARNING(PROBE, "pdata->ioaddr: 0x00000000");
 		SMSC_WARNING(PROBE, "pdata->ioaddr: 0x00000000");
@@ -1895,8 +1896,11 @@ static int __devinit smsc911x_init(struct net_device *dev)
 	/* workaround for platforms without an eeprom, where the mac address
 	/* workaround for platforms without an eeprom, where the mac address
 	 * is stored elsewhere and set by the bootloader.  This saves the
 	 * is stored elsewhere and set by the bootloader.  This saves the
 	 * mac address before resetting the device */
 	 * mac address before resetting the device */
-	if (pdata->config.flags & SMSC911X_SAVE_MAC_ADDRESS)
+	if (pdata->config.flags & SMSC911X_SAVE_MAC_ADDRESS) {
+		spin_lock_irq(&pdata->mac_lock);
 		smsc911x_read_mac_address(dev);
 		smsc911x_read_mac_address(dev);
+		spin_unlock_irq(&pdata->mac_lock);
+	}
 
 
 	/* Reset the LAN911x */
 	/* Reset the LAN911x */
 	if (smsc911x_soft_reset(pdata))
 	if (smsc911x_soft_reset(pdata))
@@ -2059,8 +2063,6 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
 		SMSC_TRACE(PROBE, "Network interface: \"%s\"", dev->name);
 		SMSC_TRACE(PROBE, "Network interface: \"%s\"", dev->name);
 	}
 	}
 
 
-	spin_lock_init(&pdata->mac_lock);
-
 	retval = smsc911x_mii_init(pdev, dev);
 	retval = smsc911x_mii_init(pdev, dev);
 	if (retval) {
 	if (retval) {
 		SMSC_WARNING(PROBE,
 		SMSC_WARNING(PROBE,

+ 15 - 0
drivers/net/usb/smsc95xx.c

@@ -1313,6 +1313,21 @@ static const struct usb_device_id products[] = {
 		USB_DEVICE(0x0424, 0x9909),
 		USB_DEVICE(0x0424, 0x9909),
 		.driver_info = (unsigned long) &smsc95xx_info,
 		.driver_info = (unsigned long) &smsc95xx_info,
 	},
 	},
+	{
+		/* SMSC LAN9530 USB Ethernet Device */
+		USB_DEVICE(0x0424, 0x9530),
+		.driver_info = (unsigned long) &smsc95xx_info,
+	},
+	{
+		/* SMSC LAN9730 USB Ethernet Device */
+		USB_DEVICE(0x0424, 0x9730),
+		.driver_info = (unsigned long) &smsc95xx_info,
+	},
+	{
+		/* SMSC LAN89530 USB Ethernet Device */
+		USB_DEVICE(0x0424, 0x9E08),
+		.driver_info = (unsigned long) &smsc95xx_info,
+	},
 	{ },		/* END */
 	{ },		/* END */
 };
 };
 MODULE_DEVICE_TABLE(usb, products);
 MODULE_DEVICE_TABLE(usb, products);

+ 1 - 0
drivers/net/wireless/ath/ath9k/hw.c

@@ -2546,6 +2546,7 @@ static struct {
 	{ AR_SREV_VERSION_9287,         "9287" },
 	{ AR_SREV_VERSION_9287,         "9287" },
 	{ AR_SREV_VERSION_9271,         "9271" },
 	{ AR_SREV_VERSION_9271,         "9271" },
 	{ AR_SREV_VERSION_9300,         "9300" },
 	{ AR_SREV_VERSION_9300,         "9300" },
+	{ AR_SREV_VERSION_9485,         "9485" },
 };
 };
 
 
 /* For devices with external radios */
 /* For devices with external radios */

+ 1 - 1
drivers/net/wireless/b43/dma.c

@@ -1536,7 +1536,7 @@ static void dma_rx(struct b43_dmaring *ring, int *slot)
 		dmaaddr = meta->dmaaddr;
 		dmaaddr = meta->dmaaddr;
 		goto drop_recycle_buffer;
 		goto drop_recycle_buffer;
 	}
 	}
-	if (unlikely(len > ring->rx_buffersize)) {
+	if (unlikely(len + ring->frameoffset > ring->rx_buffersize)) {
 		/* The data did not fit into one descriptor buffer
 		/* The data did not fit into one descriptor buffer
 		 * and is split over multiple buffers.
 		 * and is split over multiple buffers.
 		 * This should never happen, as we try to allocate buffers
 		 * This should never happen, as we try to allocate buffers

+ 1 - 1
drivers/net/wireless/b43/dma.h

@@ -163,7 +163,7 @@ struct b43_dmadesc_generic {
 /* DMA engine tuning knobs */
 /* DMA engine tuning knobs */
 #define B43_TXRING_SLOTS		256
 #define B43_TXRING_SLOTS		256
 #define B43_RXRING_SLOTS		64
 #define B43_RXRING_SLOTS		64
-#define B43_DMA0_RX_BUFFERSIZE		IEEE80211_MAX_FRAME_LEN
+#define B43_DMA0_RX_BUFFERSIZE		(B43_DMA0_RX_FRAMEOFFSET + IEEE80211_MAX_FRAME_LEN)
 
 
 /* Pointer poison */
 /* Pointer poison */
 #define B43_DMA_PTR_POISON		((void *)ERR_PTR(-ENOMEM))
 #define B43_DMA_PTR_POISON		((void *)ERR_PTR(-ENOMEM))

+ 1 - 1
drivers/net/wireless/iwlwifi/iwl-eeprom.h

@@ -241,7 +241,7 @@ struct iwl_eeprom_enhanced_txpwr {
 
 
 /* 6x00 Specific */
 /* 6x00 Specific */
 #define EEPROM_6000_TX_POWER_VERSION    (4)
 #define EEPROM_6000_TX_POWER_VERSION    (4)
-#define EEPROM_6000_EEPROM_VERSION	(0x434)
+#define EEPROM_6000_EEPROM_VERSION	(0x423)
 
 
 /* 6x50 Specific */
 /* 6x50 Specific */
 #define EEPROM_6050_TX_POWER_VERSION    (4)
 #define EEPROM_6050_TX_POWER_VERSION    (4)

+ 2 - 0
drivers/net/wireless/p54/p54usb.c

@@ -56,6 +56,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
 	{USB_DEVICE(0x0846, 0x4210)},	/* Netgear WG121 the second ? */
 	{USB_DEVICE(0x0846, 0x4210)},	/* Netgear WG121 the second ? */
 	{USB_DEVICE(0x0846, 0x4220)},	/* Netgear WG111 */
 	{USB_DEVICE(0x0846, 0x4220)},	/* Netgear WG111 */
 	{USB_DEVICE(0x09aa, 0x1000)},	/* Spinnaker Proto board */
 	{USB_DEVICE(0x09aa, 0x1000)},	/* Spinnaker Proto board */
+	{USB_DEVICE(0x0bf8, 0x1007)},	/* Fujitsu E-5400 USB */
 	{USB_DEVICE(0x0cde, 0x0006)},	/* Medion 40900, Roper Europe */
 	{USB_DEVICE(0x0cde, 0x0006)},	/* Medion 40900, Roper Europe */
 	{USB_DEVICE(0x0db0, 0x6826)},	/* MSI UB54G (MS-6826) */
 	{USB_DEVICE(0x0db0, 0x6826)},	/* MSI UB54G (MS-6826) */
 	{USB_DEVICE(0x107b, 0x55f2)},	/* Gateway WGU-210 (Gemtek) */
 	{USB_DEVICE(0x107b, 0x55f2)},	/* Gateway WGU-210 (Gemtek) */
@@ -68,6 +69,7 @@ static struct usb_device_id p54u_table[] __devinitdata = {
 	{USB_DEVICE(0x1915, 0x2235)},	/* Linksys WUSB54G Portable OEM */
 	{USB_DEVICE(0x1915, 0x2235)},	/* Linksys WUSB54G Portable OEM */
 	{USB_DEVICE(0x2001, 0x3701)},	/* DLink DWL-G120 Spinnaker */
 	{USB_DEVICE(0x2001, 0x3701)},	/* DLink DWL-G120 Spinnaker */
 	{USB_DEVICE(0x2001, 0x3703)},	/* DLink DWL-G122 */
 	{USB_DEVICE(0x2001, 0x3703)},	/* DLink DWL-G122 */
+	{USB_DEVICE(0x2001, 0x3762)},	/* Conceptronic C54U */
 	{USB_DEVICE(0x5041, 0x2234)},	/* Linksys WUSB54G */
 	{USB_DEVICE(0x5041, 0x2234)},	/* Linksys WUSB54G */
 	{USB_DEVICE(0x5041, 0x2235)},	/* Linksys WUSB54G Portable */
 	{USB_DEVICE(0x5041, 0x2235)},	/* Linksys WUSB54G Portable */
 
 

+ 4 - 2
drivers/net/wireless/rt2x00/rt2x00dev.c

@@ -1062,8 +1062,10 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
 	 * Stop all work.
 	 * Stop all work.
 	 */
 	 */
 	cancel_work_sync(&rt2x00dev->intf_work);
 	cancel_work_sync(&rt2x00dev->intf_work);
-	cancel_work_sync(&rt2x00dev->rxdone_work);
-	cancel_work_sync(&rt2x00dev->txdone_work);
+	if (rt2x00_is_usb(rt2x00dev)) {
+		cancel_work_sync(&rt2x00dev->rxdone_work);
+		cancel_work_sync(&rt2x00dev->txdone_work);
+	}
 	destroy_workqueue(rt2x00dev->workqueue);
 	destroy_workqueue(rt2x00dev->workqueue);
 
 
 	/*
 	/*

+ 1 - 1
drivers/net/wireless/rtlwifi/efuse.c

@@ -685,7 +685,7 @@ static int efuse_pg_packet_read(struct ieee80211_hw *hw, u8 offset, u8 *data)
 
 
 	u8 efuse_data, word_cnts = 0;
 	u8 efuse_data, word_cnts = 0;
 	u16 efuse_addr = 0;
 	u16 efuse_addr = 0;
-	u8 hworden;
+	u8 hworden = 0;
 	u8 tmpdata[8];
 	u8 tmpdata[8];
 
 
 	if (data == NULL)
 	if (data == NULL)

+ 1 - 1
drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c

@@ -303,7 +303,7 @@ static void _rtl92c_fill_h2c_command(struct ieee80211_hw *hw,
 	u16 box_reg, box_extreg;
 	u16 box_reg, box_extreg;
 	u8 u1b_tmp;
 	u8 u1b_tmp;
 	bool isfw_read = false;
 	bool isfw_read = false;
-	u8 buf_index;
+	u8 buf_index = 0;
 	bool bwrite_sucess = false;
 	bool bwrite_sucess = false;
 	u8 wait_h2c_limmit = 100;
 	u8 wait_h2c_limmit = 100;
 	u8 wait_writeh2c_limmit = 100;
 	u8 wait_writeh2c_limmit = 100;

+ 1 - 1
drivers/net/wireless/rtlwifi/usb.c

@@ -246,7 +246,7 @@ static void _rtl_usb_io_handler_init(struct device *dev,
 
 
 static void _rtl_usb_io_handler_release(struct ieee80211_hw *hw)
 static void _rtl_usb_io_handler_release(struct ieee80211_hw *hw)
 {
 {
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_priv __maybe_unused *rtlpriv = rtl_priv(hw);
 
 
 	mutex_destroy(&rtlpriv->io.bb_mutex);
 	mutex_destroy(&rtlpriv->io.bb_mutex);
 }
 }

+ 1 - 1
drivers/net/wireless/wl12xx/sdio.c

@@ -340,7 +340,7 @@ module_init(wl1271_init);
 module_exit(wl1271_exit);
 module_exit(wl1271_exit);
 
 
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
+MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
 MODULE_FIRMWARE(WL1271_FW_NAME);
 MODULE_FIRMWARE(WL1271_FW_NAME);
 MODULE_FIRMWARE(WL1271_AP_FW_NAME);
 MODULE_FIRMWARE(WL1271_AP_FW_NAME);

+ 1 - 1
drivers/net/wireless/wl12xx/spi.c

@@ -487,7 +487,7 @@ module_init(wl1271_init);
 module_exit(wl1271_exit);
 module_exit(wl1271_exit);
 
 
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Luciano Coelho <luciano.coelho@nokia.com>");
+MODULE_AUTHOR("Luciano Coelho <coelho@ti.com>");
 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
 MODULE_AUTHOR("Juuso Oikarinen <juuso.oikarinen@nokia.com>");
 MODULE_FIRMWARE(WL1271_FW_NAME);
 MODULE_FIRMWARE(WL1271_FW_NAME);
 MODULE_FIRMWARE(WL1271_AP_FW_NAME);
 MODULE_FIRMWARE(WL1271_AP_FW_NAME);

+ 4 - 1
drivers/net/wireless/wl12xx/testmode.c

@@ -204,7 +204,10 @@ static int wl1271_tm_cmd_nvs_push(struct wl1271 *wl, struct nlattr *tb[])
 
 
 	kfree(wl->nvs);
 	kfree(wl->nvs);
 
 
-	wl->nvs = kzalloc(sizeof(struct wl1271_nvs_file), GFP_KERNEL);
+	if (len != sizeof(struct wl1271_nvs_file))
+		return -EINVAL;
+
+	wl->nvs = kzalloc(len, GFP_KERNEL);
 	if (!wl->nvs) {
 	if (!wl->nvs) {
 		wl1271_error("could not allocate memory for the nvs file");
 		wl1271_error("could not allocate memory for the nvs file");
 		ret = -ENOMEM;
 		ret = -ENOMEM;

+ 18 - 2
drivers/net/wireless/zd1211rw/zd_usb.c

@@ -643,7 +643,7 @@ static void rx_urb_complete(struct urb *urb)
 	usb = urb->context;
 	usb = urb->context;
 	rx = &usb->rx;
 	rx = &usb->rx;
 
 
-	zd_usb_reset_rx_idle_timer(usb);
+	tasklet_schedule(&rx->reset_timer_tasklet);
 
 
 	if (length%rx->usb_packet_size > rx->usb_packet_size-4) {
 	if (length%rx->usb_packet_size > rx->usb_packet_size-4) {
 		/* If there is an old first fragment, we don't care. */
 		/* If there is an old first fragment, we don't care. */
@@ -812,6 +812,7 @@ void zd_usb_disable_rx(struct zd_usb *usb)
 	__zd_usb_disable_rx(usb);
 	__zd_usb_disable_rx(usb);
 	mutex_unlock(&rx->setup_mutex);
 	mutex_unlock(&rx->setup_mutex);
 
 
+	tasklet_kill(&rx->reset_timer_tasklet);
 	cancel_delayed_work_sync(&rx->idle_work);
 	cancel_delayed_work_sync(&rx->idle_work);
 }
 }
 
 
@@ -1106,6 +1107,13 @@ static void zd_rx_idle_timer_handler(struct work_struct *work)
 	zd_usb_reset_rx(usb);
 	zd_usb_reset_rx(usb);
 }
 }
 
 
+static void zd_usb_reset_rx_idle_timer_tasklet(unsigned long param)
+{
+	struct zd_usb *usb = (struct zd_usb *)param;
+
+	zd_usb_reset_rx_idle_timer(usb);
+}
+
 void zd_usb_reset_rx_idle_timer(struct zd_usb *usb)
 void zd_usb_reset_rx_idle_timer(struct zd_usb *usb)
 {
 {
 	struct zd_usb_rx *rx = &usb->rx;
 	struct zd_usb_rx *rx = &usb->rx;
@@ -1127,6 +1135,7 @@ static inline void init_usb_interrupt(struct zd_usb *usb)
 static inline void init_usb_rx(struct zd_usb *usb)
 static inline void init_usb_rx(struct zd_usb *usb)
 {
 {
 	struct zd_usb_rx *rx = &usb->rx;
 	struct zd_usb_rx *rx = &usb->rx;
+
 	spin_lock_init(&rx->lock);
 	spin_lock_init(&rx->lock);
 	mutex_init(&rx->setup_mutex);
 	mutex_init(&rx->setup_mutex);
 	if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH) {
 	if (interface_to_usbdev(usb->intf)->speed == USB_SPEED_HIGH) {
@@ -1136,11 +1145,14 @@ static inline void init_usb_rx(struct zd_usb *usb)
 	}
 	}
 	ZD_ASSERT(rx->fragment_length == 0);
 	ZD_ASSERT(rx->fragment_length == 0);
 	INIT_DELAYED_WORK(&rx->idle_work, zd_rx_idle_timer_handler);
 	INIT_DELAYED_WORK(&rx->idle_work, zd_rx_idle_timer_handler);
+	rx->reset_timer_tasklet.func = zd_usb_reset_rx_idle_timer_tasklet;
+	rx->reset_timer_tasklet.data = (unsigned long)usb;
 }
 }
 
 
 static inline void init_usb_tx(struct zd_usb *usb)
 static inline void init_usb_tx(struct zd_usb *usb)
 {
 {
 	struct zd_usb_tx *tx = &usb->tx;
 	struct zd_usb_tx *tx = &usb->tx;
+
 	spin_lock_init(&tx->lock);
 	spin_lock_init(&tx->lock);
 	atomic_set(&tx->enabled, 0);
 	atomic_set(&tx->enabled, 0);
 	tx->stopped = 0;
 	tx->stopped = 0;
@@ -1671,6 +1683,10 @@ static void iowrite16v_urb_complete(struct urb *urb)
 
 
 	if (urb->status && !usb->cmd_error)
 	if (urb->status && !usb->cmd_error)
 		usb->cmd_error = urb->status;
 		usb->cmd_error = urb->status;
+
+	if (!usb->cmd_error &&
+			urb->actual_length != urb->transfer_buffer_length)
+		usb->cmd_error = -EIO;
 }
 }
 
 
 static int zd_submit_waiting_urb(struct zd_usb *usb, bool last)
 static int zd_submit_waiting_urb(struct zd_usb *usb, bool last)
@@ -1805,7 +1821,7 @@ int zd_usb_iowrite16v_async(struct zd_usb *usb, const struct zd_ioreq16 *ioreqs,
 	usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
 	usb_fill_int_urb(urb, udev, usb_sndintpipe(udev, EP_REGS_OUT),
 			 req, req_len, iowrite16v_urb_complete, usb,
 			 req, req_len, iowrite16v_urb_complete, usb,
 			 ep->desc.bInterval);
 			 ep->desc.bInterval);
-	urb->transfer_flags |= URB_FREE_BUFFER | URB_SHORT_NOT_OK;
+	urb->transfer_flags |= URB_FREE_BUFFER;
 
 
 	/* Submit previous URB */
 	/* Submit previous URB */
 	r = zd_submit_waiting_urb(usb, false);
 	r = zd_submit_waiting_urb(usb, false);

+ 1 - 0
drivers/net/wireless/zd1211rw/zd_usb.h

@@ -183,6 +183,7 @@ struct zd_usb_rx {
 	spinlock_t lock;
 	spinlock_t lock;
 	struct mutex setup_mutex;
 	struct mutex setup_mutex;
 	struct delayed_work idle_work;
 	struct delayed_work idle_work;
+	struct tasklet_struct reset_timer_tasklet;
 	u8 fragment[2 * USB_MAX_RX_SIZE];
 	u8 fragment[2 * USB_MAX_RX_SIZE];
 	unsigned int fragment_length;
 	unsigned int fragment_length;
 	unsigned int usb_packet_size;
 	unsigned int usb_packet_size;

+ 2 - 0
include/linux/can/platform/mcp251x.h

@@ -12,6 +12,7 @@
 /**
 /**
  * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data
  * struct mcp251x_platform_data - MCP251X SPI CAN controller platform data
  * @oscillator_frequency:       - oscillator frequency in Hz
  * @oscillator_frequency:       - oscillator frequency in Hz
+ * @irq_flags:                  - IRQF configuration flags
  * @board_specific_setup:       - called before probing the chip (power,reset)
  * @board_specific_setup:       - called before probing the chip (power,reset)
  * @transceiver_enable:         - called to power on/off the transceiver
  * @transceiver_enable:         - called to power on/off the transceiver
  * @power_enable:               - called to power on/off the mcp *and* the
  * @power_enable:               - called to power on/off the mcp *and* the
@@ -24,6 +25,7 @@
 
 
 struct mcp251x_platform_data {
 struct mcp251x_platform_data {
 	unsigned long oscillator_frequency;
 	unsigned long oscillator_frequency;
+	unsigned long irq_flags;
 	int (*board_specific_setup)(struct spi_device *spi);
 	int (*board_specific_setup)(struct spi_device *spi);
 	int (*transceiver_enable)(int enable);
 	int (*transceiver_enable)(int enable);
 	int (*power_enable) (int enable);
 	int (*power_enable) (int enable);

+ 2 - 1
include/linux/netfilter.h

@@ -270,7 +270,8 @@ struct nf_afinfo {
 					    unsigned int dataoff,
 					    unsigned int dataoff,
 					    unsigned int len,
 					    unsigned int len,
 					    u_int8_t protocol);
 					    u_int8_t protocol);
-	int		(*route)(struct dst_entry **dst, struct flowi *fl);
+	int		(*route)(struct net *net, struct dst_entry **dst,
+				 struct flowi *fl, bool strict);
 	void		(*saveroute)(const struct sk_buff *skb,
 	void		(*saveroute)(const struct sk_buff *skb,
 				     struct nf_queue_entry *entry);
 				     struct nf_queue_entry *entry);
 	int		(*reroute)(struct sk_buff *skb,
 	int		(*reroute)(struct sk_buff *skb,

+ 1 - 1
include/linux/netfilter/ipset/ip_set.h

@@ -293,7 +293,7 @@ struct ip_set {
 	/* Lock protecting the set data */
 	/* Lock protecting the set data */
 	rwlock_t lock;
 	rwlock_t lock;
 	/* References to the set */
 	/* References to the set */
-	atomic_t ref;
+	u32 ref;
 	/* The core set type */
 	/* The core set type */
 	struct ip_set_type *type;
 	struct ip_set_type *type;
 	/* The type variant doing the real job */
 	/* The type variant doing the real job */

+ 1 - 2
include/linux/netfilter/ipset/ip_set_ahash.h

@@ -515,8 +515,7 @@ type_pf_head(struct ip_set *set, struct sk_buff *skb)
 	if (h->netmask != HOST_MASK)
 	if (h->netmask != HOST_MASK)
 		NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, h->netmask);
 		NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, h->netmask);
 #endif
 #endif
-	NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES,
-		      htonl(atomic_read(&set->ref) - 1));
+	NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
 	NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize));
 	NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE, htonl(memsize));
 	if (with_timeout(h->timeout))
 	if (with_timeout(h->timeout))
 		NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout));
 		NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(h->timeout));

+ 1 - 1
include/net/ip_vs.h

@@ -52,7 +52,7 @@ static inline struct net *skb_net(const struct sk_buff *skb)
 	 */
 	 */
 	if (likely(skb->dev && skb->dev->nd_net))
 	if (likely(skb->dev && skb->dev->nd_net))
 		return dev_net(skb->dev);
 		return dev_net(skb->dev);
-	if (skb_dst(skb)->dev)
+	if (skb_dst(skb) && skb_dst(skb)->dev)
 		return dev_net(skb_dst(skb)->dev);
 		return dev_net(skb_dst(skb)->dev);
 	WARN(skb->sk, "Maybe skb_sknet should be used in %s() at line:%d\n",
 	WARN(skb->sk, "Maybe skb_sknet should be used in %s() at line:%d\n",
 		      __func__, __LINE__);
 		      __func__, __LINE__);

+ 13 - 2
include/net/mac80211.h

@@ -1753,8 +1753,19 @@ enum ieee80211_ampdu_mlme_action {
  * 	that TX/RX_STOP can pass NULL for this parameter.
  * 	that TX/RX_STOP can pass NULL for this parameter.
  *	The @buf_size parameter is only valid when the action is set to
  *	The @buf_size parameter is only valid when the action is set to
  *	%IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's reorder
  *	%IEEE80211_AMPDU_TX_OPERATIONAL and indicates the peer's reorder
- *	buffer size (number of subframes) for this session -- aggregates
- *	containing more subframes than this may not be transmitted to the peer.
+ *	buffer size (number of subframes) for this session -- the driver
+ *	may neither send aggregates containing more subframes than this
+ *	nor send aggregates in a way that lost frames would exceed the
+ *	buffer size. If just limiting the aggregate size, this would be
+ *	possible with a buf_size of 8:
+ *	 - TX: 1.....7
+ *	 - RX:  2....7 (lost frame #1)
+ *	 - TX:        8..1...
+ *	which is invalid since #1 was now re-transmitted well past the
+ *	buffer size of 8. Correct ways to retransmit #1 would be:
+ *	 - TX:       1 or 18 or 81
+ *	Even "189" would be wrong since 1 could be lost again.
+ *
  *	Returns a negative error code on failure.
  *	Returns a negative error code on failure.
  *	The callback can sleep.
  *	The callback can sleep.
  *
  *

+ 3 - 2
include/net/route.h

@@ -64,6 +64,7 @@ struct rtable {
 
 
 	__be32			rt_dst;	/* Path destination	*/
 	__be32			rt_dst;	/* Path destination	*/
 	__be32			rt_src;	/* Path source		*/
 	__be32			rt_src;	/* Path source		*/
+	int			rt_route_iif;
 	int			rt_iif;
 	int			rt_iif;
 	int			rt_oif;
 	int			rt_oif;
 	__u32			rt_mark;
 	__u32			rt_mark;
@@ -80,12 +81,12 @@ struct rtable {
 
 
 static inline bool rt_is_input_route(struct rtable *rt)
 static inline bool rt_is_input_route(struct rtable *rt)
 {
 {
-	return rt->rt_iif != 0;
+	return rt->rt_route_iif != 0;
 }
 }
 
 
 static inline bool rt_is_output_route(struct rtable *rt)
 static inline bool rt_is_output_route(struct rtable *rt)
 {
 {
-	return rt->rt_iif == 0;
+	return rt->rt_route_iif == 0;
 }
 }
 
 
 struct ip_rt_acct {
 struct ip_rt_acct {

+ 19 - 4
net/dsa/mv88e6131.c

@@ -14,6 +14,13 @@
 #include "dsa_priv.h"
 #include "dsa_priv.h"
 #include "mv88e6xxx.h"
 #include "mv88e6xxx.h"
 
 
+/*
+ * Switch product IDs
+ */
+#define ID_6085		0x04a0
+#define ID_6095		0x0950
+#define ID_6131		0x1060
+
 static char *mv88e6131_probe(struct mii_bus *bus, int sw_addr)
 static char *mv88e6131_probe(struct mii_bus *bus, int sw_addr)
 {
 {
 	int ret;
 	int ret;
@@ -21,9 +28,11 @@ static char *mv88e6131_probe(struct mii_bus *bus, int sw_addr)
 	ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
 	ret = __mv88e6xxx_reg_read(bus, sw_addr, REG_PORT(0), 0x03);
 	if (ret >= 0) {
 	if (ret >= 0) {
 		ret &= 0xfff0;
 		ret &= 0xfff0;
-		if (ret == 0x0950)
+		if (ret == ID_6085)
+			return "Marvell 88E6085";
+		if (ret == ID_6095)
 			return "Marvell 88E6095/88E6095F";
 			return "Marvell 88E6095/88E6095F";
-		if (ret == 0x1060)
+		if (ret == ID_6131)
 			return "Marvell 88E6131";
 			return "Marvell 88E6131";
 	}
 	}
 
 
@@ -164,6 +173,7 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
 
 
 static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
 static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
 {
 {
+	struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
 	int addr = REG_PORT(p);
 	int addr = REG_PORT(p);
 	u16 val;
 	u16 val;
 
 
@@ -171,10 +181,13 @@ static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
 	 * MAC Forcing register: don't force link, speed, duplex
 	 * MAC Forcing register: don't force link, speed, duplex
 	 * or flow control state to any particular values on physical
 	 * or flow control state to any particular values on physical
 	 * ports, but force the CPU port and all DSA ports to 1000 Mb/s
 	 * ports, but force the CPU port and all DSA ports to 1000 Mb/s
-	 * full duplex.
+	 * (100 Mb/s on 6085) full duplex.
 	 */
 	 */
 	if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
 	if (dsa_is_cpu_port(ds, p) || ds->dsa_port_mask & (1 << p))
-		REG_WRITE(addr, 0x01, 0x003e);
+		if (ps->id == ID_6085)
+			REG_WRITE(addr, 0x01, 0x003d); /* 100 Mb/s */
+		else
+			REG_WRITE(addr, 0x01, 0x003e); /* 1000 Mb/s */
 	else
 	else
 		REG_WRITE(addr, 0x01, 0x0003);
 		REG_WRITE(addr, 0x01, 0x0003);
 
 
@@ -286,6 +299,8 @@ static int mv88e6131_setup(struct dsa_switch *ds)
 	mv88e6xxx_ppu_state_init(ds);
 	mv88e6xxx_ppu_state_init(ds);
 	mutex_init(&ps->stats_mutex);
 	mutex_init(&ps->stats_mutex);
 
 
+	ps->id = REG_READ(REG_PORT(0), 0x03) & 0xfff0;
+
 	ret = mv88e6131_switch_reset(ds);
 	ret = mv88e6131_switch_reset(ds);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;

+ 2 - 0
net/dsa/mv88e6xxx.h

@@ -39,6 +39,8 @@ struct mv88e6xxx_priv_state {
 	 * Hold this mutex over snapshot + dump sequences.
 	 * Hold this mutex over snapshot + dump sequences.
 	 */
 	 */
 	struct mutex	stats_mutex;
 	struct mutex	stats_mutex;
+
+	int		id; /* switch product id */
 };
 };
 
 
 struct mv88e6xxx_hw_stat {
 struct mv88e6xxx_hw_stat {

+ 3 - 2
net/ipv4/netfilter.c

@@ -221,9 +221,10 @@ static __sum16 nf_ip_checksum_partial(struct sk_buff *skb, unsigned int hook,
 	return csum;
 	return csum;
 }
 }
 
 
-static int nf_ip_route(struct dst_entry **dst, struct flowi *fl)
+static int nf_ip_route(struct net *net, struct dst_entry **dst,
+		       struct flowi *fl, bool strict __always_unused)
 {
 {
-	struct rtable *rt = ip_route_output_key(&init_net, &fl->u.ip4);
+	struct rtable *rt = ip_route_output_key(net, &fl->u.ip4);
 	if (IS_ERR(rt))
 	if (IS_ERR(rt))
 		return PTR_ERR(rt);
 		return PTR_ERR(rt);
 	*dst = &rt->dst;
 	*dst = &rt->dst;

+ 6 - 2
net/ipv4/route.c

@@ -1891,6 +1891,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 #ifdef CONFIG_IP_ROUTE_CLASSID
 #ifdef CONFIG_IP_ROUTE_CLASSID
 	rth->dst.tclassid = itag;
 	rth->dst.tclassid = itag;
 #endif
 #endif
+	rth->rt_route_iif = dev->ifindex;
 	rth->rt_iif	= dev->ifindex;
 	rth->rt_iif	= dev->ifindex;
 	rth->dst.dev	= init_net.loopback_dev;
 	rth->dst.dev	= init_net.loopback_dev;
 	dev_hold(rth->dst.dev);
 	dev_hold(rth->dst.dev);
@@ -2026,6 +2027,7 @@ static int __mkroute_input(struct sk_buff *skb,
 	rth->rt_key_src	= saddr;
 	rth->rt_key_src	= saddr;
 	rth->rt_src	= saddr;
 	rth->rt_src	= saddr;
 	rth->rt_gateway	= daddr;
 	rth->rt_gateway	= daddr;
+	rth->rt_route_iif = in_dev->dev->ifindex;
 	rth->rt_iif 	= in_dev->dev->ifindex;
 	rth->rt_iif 	= in_dev->dev->ifindex;
 	rth->dst.dev	= (out_dev)->dev;
 	rth->dst.dev	= (out_dev)->dev;
 	dev_hold(rth->dst.dev);
 	dev_hold(rth->dst.dev);
@@ -2202,6 +2204,7 @@ local_input:
 #ifdef CONFIG_IP_ROUTE_CLASSID
 #ifdef CONFIG_IP_ROUTE_CLASSID
 	rth->dst.tclassid = itag;
 	rth->dst.tclassid = itag;
 #endif
 #endif
+	rth->rt_route_iif = dev->ifindex;
 	rth->rt_iif	= dev->ifindex;
 	rth->rt_iif	= dev->ifindex;
 	rth->dst.dev	= net->loopback_dev;
 	rth->dst.dev	= net->loopback_dev;
 	dev_hold(rth->dst.dev);
 	dev_hold(rth->dst.dev);
@@ -2401,7 +2404,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
 	rth->rt_mark    = oldflp4->flowi4_mark;
 	rth->rt_mark    = oldflp4->flowi4_mark;
 	rth->rt_dst	= fl4->daddr;
 	rth->rt_dst	= fl4->daddr;
 	rth->rt_src	= fl4->saddr;
 	rth->rt_src	= fl4->saddr;
-	rth->rt_iif	= 0;
+	rth->rt_route_iif = 0;
+	rth->rt_iif	= oldflp4->flowi4_oif ? : dev_out->ifindex;
 	/* get references to the devices that are to be hold by the routing
 	/* get references to the devices that are to be hold by the routing
 	   cache entry */
 	   cache entry */
 	rth->dst.dev	= dev_out;
 	rth->dst.dev	= dev_out;
@@ -2716,6 +2720,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
 		rt->rt_key_dst = ort->rt_key_dst;
 		rt->rt_key_dst = ort->rt_key_dst;
 		rt->rt_key_src = ort->rt_key_src;
 		rt->rt_key_src = ort->rt_key_src;
 		rt->rt_tos = ort->rt_tos;
 		rt->rt_tos = ort->rt_tos;
+		rt->rt_route_iif = ort->rt_route_iif;
 		rt->rt_iif = ort->rt_iif;
 		rt->rt_iif = ort->rt_iif;
 		rt->rt_oif = ort->rt_oif;
 		rt->rt_oif = ort->rt_oif;
 		rt->rt_mark = ort->rt_mark;
 		rt->rt_mark = ort->rt_mark;
@@ -2725,7 +2730,6 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
 		rt->rt_type = ort->rt_type;
 		rt->rt_type = ort->rt_type;
 		rt->rt_dst = ort->rt_dst;
 		rt->rt_dst = ort->rt_dst;
 		rt->rt_src = ort->rt_src;
 		rt->rt_src = ort->rt_src;
-		rt->rt_iif = ort->rt_iif;
 		rt->rt_gateway = ort->rt_gateway;
 		rt->rt_gateway = ort->rt_gateway;
 		rt->rt_spec_dst = ort->rt_spec_dst;
 		rt->rt_spec_dst = ort->rt_spec_dst;
 		rt->peer = ort->peer;
 		rt->peer = ort->peer;

+ 1 - 0
net/ipv4/xfrm4_policy.c

@@ -74,6 +74,7 @@ static int xfrm4_fill_dst(struct xfrm_dst *xdst, struct net_device *dev,
 	rt->rt_key_dst = fl4->daddr;
 	rt->rt_key_dst = fl4->daddr;
 	rt->rt_key_src = fl4->saddr;
 	rt->rt_key_src = fl4->saddr;
 	rt->rt_tos = fl4->flowi4_tos;
 	rt->rt_tos = fl4->flowi4_tos;
+	rt->rt_route_iif = fl4->flowi4_iif;
 	rt->rt_iif = fl4->flowi4_iif;
 	rt->rt_iif = fl4->flowi4_iif;
 	rt->rt_oif = fl4->flowi4_oif;
 	rt->rt_oif = fl4->flowi4_oif;
 	rt->rt_mark = fl4->flowi4_mark;
 	rt->rt_mark = fl4->flowi4_mark;

+ 11 - 2
net/ipv6/netfilter.c

@@ -90,9 +90,18 @@ static int nf_ip6_reroute(struct sk_buff *skb,
 	return 0;
 	return 0;
 }
 }
 
 
-static int nf_ip6_route(struct dst_entry **dst, struct flowi *fl)
+static int nf_ip6_route(struct net *net, struct dst_entry **dst,
+			struct flowi *fl, bool strict)
 {
 {
-	*dst = ip6_route_output(&init_net, NULL, &fl->u.ip6);
+	static const struct ipv6_pinfo fake_pinfo;
+	static const struct inet_sock fake_sk = {
+		/* makes ip6_route_output set RT6_LOOKUP_F_IFACE: */
+		.sk.sk_bound_dev_if = 1,
+		.pinet6 = (struct ipv6_pinfo *) &fake_pinfo,
+	};
+	const void *sk = strict ? &fake_sk : NULL;
+
+	*dst = ip6_route_output(net, sk, &fl->u.ip6);
 	return (*dst)->error;
 	return (*dst)->error;
 }
 }
 
 

+ 3 - 1
net/ipv6/tcp_ipv6.c

@@ -1622,6 +1622,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 		opt_skb = skb_clone(skb, GFP_ATOMIC);
 		opt_skb = skb_clone(skb, GFP_ATOMIC);
 
 
 	if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
 	if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */
+		sock_rps_save_rxhash(sk, skb->rxhash);
 		if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len))
 		if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len))
 			goto reset;
 			goto reset;
 		if (opt_skb)
 		if (opt_skb)
@@ -1649,7 +1650,8 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb)
 				__kfree_skb(opt_skb);
 				__kfree_skb(opt_skb);
 			return 0;
 			return 0;
 		}
 		}
-	}
+	} else
+		sock_rps_save_rxhash(sk, skb->rxhash);
 
 
 	if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len))
 	if (tcp_rcv_state_process(sk, skb, tcp_hdr(skb), skb->len))
 		goto reset;
 		goto reset;

+ 3 - 0
net/ipv6/udp.c

@@ -505,6 +505,9 @@ int udpv6_queue_rcv_skb(struct sock * sk, struct sk_buff *skb)
 	int rc;
 	int rc;
 	int is_udplite = IS_UDPLITE(sk);
 	int is_udplite = IS_UDPLITE(sk);
 
 
+	if (!ipv6_addr_any(&inet6_sk(sk)->daddr))
+		sock_rps_save_rxhash(sk, skb->rxhash);
+
 	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
 	if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb))
 		goto drop;
 		goto drop;
 
 

+ 1 - 1
net/mac80211/rx.c

@@ -2541,7 +2541,6 @@ static void ieee80211_rx_handlers(struct ieee80211_rx_data *rx)
 		 * same TID from the same station
 		 * same TID from the same station
 		 */
 		 */
 		rx->skb = skb;
 		rx->skb = skb;
-		rx->flags = 0;
 
 
 		CALL_RXH(ieee80211_rx_h_decrypt)
 		CALL_RXH(ieee80211_rx_h_decrypt)
 		CALL_RXH(ieee80211_rx_h_check_more_data)
 		CALL_RXH(ieee80211_rx_h_check_more_data)
@@ -2612,6 +2611,7 @@ void ieee80211_release_reorder_timeout(struct sta_info *sta, int tid)
 		.sdata = sta->sdata,
 		.sdata = sta->sdata,
 		.local = sta->local,
 		.local = sta->local,
 		.queue = tid,
 		.queue = tid,
+		.flags = 0,
 	};
 	};
 	struct tid_ampdu_rx *tid_agg_rx;
 	struct tid_ampdu_rx *tid_agg_rx;
 
 

+ 0 - 1
net/netfilter/Kconfig

@@ -652,7 +652,6 @@ comment "Xtables matches"
 config NETFILTER_XT_MATCH_ADDRTYPE
 config NETFILTER_XT_MATCH_ADDRTYPE
 	tristate '"addrtype" address type match support'
 	tristate '"addrtype" address type match support'
 	depends on NETFILTER_ADVANCED
 	depends on NETFILTER_ADVANCED
-	depends on (IPV6 || IPV6=n)
 	---help---
 	---help---
 	  This option allows you to match what routing thinks of an address,
 	  This option allows you to match what routing thinks of an address,
 	  eg. UNICAST, LOCAL, BROADCAST, ...
 	  eg. UNICAST, LOCAL, BROADCAST, ...

+ 1 - 2
net/netfilter/ipset/ip_set_bitmap_ip.c

@@ -338,8 +338,7 @@ bitmap_ip_head(struct ip_set *set, struct sk_buff *skb)
 	NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip));
 	NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip));
 	if (map->netmask != 32)
 	if (map->netmask != 32)
 		NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, map->netmask);
 		NLA_PUT_U8(skb, IPSET_ATTR_NETMASK, map->netmask);
-	NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES,
-		      htonl(atomic_read(&set->ref) - 1));
+	NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
 	NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
 	NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
 		      htonl(sizeof(*map) + map->memsize));
 		      htonl(sizeof(*map) + map->memsize));
 	if (with_timeout(map->timeout))
 	if (with_timeout(map->timeout))

+ 1 - 2
net/netfilter/ipset/ip_set_bitmap_ipmac.c

@@ -434,8 +434,7 @@ bitmap_ipmac_head(struct ip_set *set, struct sk_buff *skb)
 		goto nla_put_failure;
 		goto nla_put_failure;
 	NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, htonl(map->first_ip));
 	NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP, htonl(map->first_ip));
 	NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip));
 	NLA_PUT_IPADDR4(skb, IPSET_ATTR_IP_TO, htonl(map->last_ip));
-	NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES,
-		      htonl(atomic_read(&set->ref) - 1));
+	NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
 	NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
 	NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
 		      htonl(sizeof(*map)
 		      htonl(sizeof(*map)
 			    + (map->last_ip - map->first_ip + 1) * map->dsize));
 			    + (map->last_ip - map->first_ip + 1) * map->dsize));

+ 1 - 2
net/netfilter/ipset/ip_set_bitmap_port.c

@@ -320,8 +320,7 @@ bitmap_port_head(struct ip_set *set, struct sk_buff *skb)
 		goto nla_put_failure;
 		goto nla_put_failure;
 	NLA_PUT_NET16(skb, IPSET_ATTR_PORT, htons(map->first_port));
 	NLA_PUT_NET16(skb, IPSET_ATTR_PORT, htons(map->first_port));
 	NLA_PUT_NET16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port));
 	NLA_PUT_NET16(skb, IPSET_ATTR_PORT_TO, htons(map->last_port));
-	NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES,
-		      htonl(atomic_read(&set->ref) - 1));
+	NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
 	NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
 	NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
 		      htonl(sizeof(*map) + map->memsize));
 		      htonl(sizeof(*map) + map->memsize));
 	if (with_timeout(map->timeout))
 	if (with_timeout(map->timeout))

+ 66 - 43
net/netfilter/ipset/ip_set_core.c

@@ -26,6 +26,7 @@
 
 
 static LIST_HEAD(ip_set_type_list);		/* all registered set types */
 static LIST_HEAD(ip_set_type_list);		/* all registered set types */
 static DEFINE_MUTEX(ip_set_type_mutex);		/* protects ip_set_type_list */
 static DEFINE_MUTEX(ip_set_type_mutex);		/* protects ip_set_type_list */
+static DEFINE_RWLOCK(ip_set_ref_lock);		/* protects the set refs */
 
 
 static struct ip_set **ip_set_list;		/* all individual sets */
 static struct ip_set **ip_set_list;		/* all individual sets */
 static ip_set_id_t ip_set_max = CONFIG_IP_SET_MAX; /* max number of sets */
 static ip_set_id_t ip_set_max = CONFIG_IP_SET_MAX; /* max number of sets */
@@ -301,13 +302,18 @@ EXPORT_SYMBOL_GPL(ip_set_get_ipaddr6);
 static inline void
 static inline void
 __ip_set_get(ip_set_id_t index)
 __ip_set_get(ip_set_id_t index)
 {
 {
-	atomic_inc(&ip_set_list[index]->ref);
+	write_lock_bh(&ip_set_ref_lock);
+	ip_set_list[index]->ref++;
+	write_unlock_bh(&ip_set_ref_lock);
 }
 }
 
 
 static inline void
 static inline void
 __ip_set_put(ip_set_id_t index)
 __ip_set_put(ip_set_id_t index)
 {
 {
-	atomic_dec(&ip_set_list[index]->ref);
+	write_lock_bh(&ip_set_ref_lock);
+	BUG_ON(ip_set_list[index]->ref == 0);
+	ip_set_list[index]->ref--;
+	write_unlock_bh(&ip_set_ref_lock);
 }
 }
 
 
 /*
 /*
@@ -324,7 +330,7 @@ ip_set_test(ip_set_id_t index, const struct sk_buff *skb,
 	struct ip_set *set = ip_set_list[index];
 	struct ip_set *set = ip_set_list[index];
 	int ret = 0;
 	int ret = 0;
 
 
-	BUG_ON(set == NULL || atomic_read(&set->ref) == 0);
+	BUG_ON(set == NULL);
 	pr_debug("set %s, index %u\n", set->name, index);
 	pr_debug("set %s, index %u\n", set->name, index);
 
 
 	if (dim < set->type->dimension ||
 	if (dim < set->type->dimension ||
@@ -356,7 +362,7 @@ ip_set_add(ip_set_id_t index, const struct sk_buff *skb,
 	struct ip_set *set = ip_set_list[index];
 	struct ip_set *set = ip_set_list[index];
 	int ret;
 	int ret;
 
 
-	BUG_ON(set == NULL || atomic_read(&set->ref) == 0);
+	BUG_ON(set == NULL);
 	pr_debug("set %s, index %u\n", set->name, index);
 	pr_debug("set %s, index %u\n", set->name, index);
 
 
 	if (dim < set->type->dimension ||
 	if (dim < set->type->dimension ||
@@ -378,7 +384,7 @@ ip_set_del(ip_set_id_t index, const struct sk_buff *skb,
 	struct ip_set *set = ip_set_list[index];
 	struct ip_set *set = ip_set_list[index];
 	int ret = 0;
 	int ret = 0;
 
 
-	BUG_ON(set == NULL || atomic_read(&set->ref) == 0);
+	BUG_ON(set == NULL);
 	pr_debug("set %s, index %u\n", set->name, index);
 	pr_debug("set %s, index %u\n", set->name, index);
 
 
 	if (dim < set->type->dimension ||
 	if (dim < set->type->dimension ||
@@ -397,7 +403,6 @@ EXPORT_SYMBOL_GPL(ip_set_del);
  * Find set by name, reference it once. The reference makes sure the
  * Find set by name, reference it once. The reference makes sure the
  * thing pointed to, does not go away under our feet.
  * thing pointed to, does not go away under our feet.
  *
  *
- * The nfnl mutex must already be activated.
  */
  */
 ip_set_id_t
 ip_set_id_t
 ip_set_get_byname(const char *name, struct ip_set **set)
 ip_set_get_byname(const char *name, struct ip_set **set)
@@ -423,15 +428,12 @@ EXPORT_SYMBOL_GPL(ip_set_get_byname);
  * reference count by 1. The caller shall not assume the index
  * reference count by 1. The caller shall not assume the index
  * to be valid, after calling this function.
  * to be valid, after calling this function.
  *
  *
- * The nfnl mutex must already be activated.
  */
  */
 void
 void
 ip_set_put_byindex(ip_set_id_t index)
 ip_set_put_byindex(ip_set_id_t index)
 {
 {
-	if (ip_set_list[index] != NULL) {
-		BUG_ON(atomic_read(&ip_set_list[index]->ref) == 0);
+	if (ip_set_list[index] != NULL)
 		__ip_set_put(index);
 		__ip_set_put(index);
-	}
 }
 }
 EXPORT_SYMBOL_GPL(ip_set_put_byindex);
 EXPORT_SYMBOL_GPL(ip_set_put_byindex);
 
 
@@ -441,7 +443,6 @@ EXPORT_SYMBOL_GPL(ip_set_put_byindex);
  * can't be destroyed. The set cannot be renamed due to
  * can't be destroyed. The set cannot be renamed due to
  * the referencing either.
  * the referencing either.
  *
  *
- * The nfnl mutex must already be activated.
  */
  */
 const char *
 const char *
 ip_set_name_byindex(ip_set_id_t index)
 ip_set_name_byindex(ip_set_id_t index)
@@ -449,7 +450,7 @@ ip_set_name_byindex(ip_set_id_t index)
 	const struct ip_set *set = ip_set_list[index];
 	const struct ip_set *set = ip_set_list[index];
 
 
 	BUG_ON(set == NULL);
 	BUG_ON(set == NULL);
-	BUG_ON(atomic_read(&set->ref) == 0);
+	BUG_ON(set->ref == 0);
 
 
 	/* Referenced, so it's safe */
 	/* Referenced, so it's safe */
 	return set->name;
 	return set->name;
@@ -515,10 +516,7 @@ void
 ip_set_nfnl_put(ip_set_id_t index)
 ip_set_nfnl_put(ip_set_id_t index)
 {
 {
 	nfnl_lock();
 	nfnl_lock();
-	if (ip_set_list[index] != NULL) {
-		BUG_ON(atomic_read(&ip_set_list[index]->ref) == 0);
-		__ip_set_put(index);
-	}
+	ip_set_put_byindex(index);
 	nfnl_unlock();
 	nfnl_unlock();
 }
 }
 EXPORT_SYMBOL_GPL(ip_set_nfnl_put);
 EXPORT_SYMBOL_GPL(ip_set_nfnl_put);
@@ -526,7 +524,7 @@ EXPORT_SYMBOL_GPL(ip_set_nfnl_put);
 /*
 /*
  * Communication protocol with userspace over netlink.
  * Communication protocol with userspace over netlink.
  *
  *
- * We already locked by nfnl_lock.
+ * The commands are serialized by the nfnl mutex.
  */
  */
 
 
 static inline bool
 static inline bool
@@ -657,7 +655,6 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
 		return -ENOMEM;
 		return -ENOMEM;
 	rwlock_init(&set->lock);
 	rwlock_init(&set->lock);
 	strlcpy(set->name, name, IPSET_MAXNAMELEN);
 	strlcpy(set->name, name, IPSET_MAXNAMELEN);
-	atomic_set(&set->ref, 0);
 	set->family = family;
 	set->family = family;
 
 
 	/*
 	/*
@@ -690,8 +687,8 @@ ip_set_create(struct sock *ctnl, struct sk_buff *skb,
 
 
 	/*
 	/*
 	 * Here, we have a valid, constructed set and we are protected
 	 * Here, we have a valid, constructed set and we are protected
-	 * by nfnl_lock. Find the first free index in ip_set_list and
-	 * check clashing.
+	 * by the nfnl mutex. Find the first free index in ip_set_list
+	 * and check clashing.
 	 */
 	 */
 	if ((ret = find_free_id(set->name, &index, &clash)) != 0) {
 	if ((ret = find_free_id(set->name, &index, &clash)) != 0) {
 		/* If this is the same set and requested, ignore error */
 		/* If this is the same set and requested, ignore error */
@@ -751,31 +748,51 @@ ip_set_destroy(struct sock *ctnl, struct sk_buff *skb,
 	       const struct nlattr * const attr[])
 	       const struct nlattr * const attr[])
 {
 {
 	ip_set_id_t i;
 	ip_set_id_t i;
+	int ret = 0;
 
 
 	if (unlikely(protocol_failed(attr)))
 	if (unlikely(protocol_failed(attr)))
 		return -IPSET_ERR_PROTOCOL;
 		return -IPSET_ERR_PROTOCOL;
 
 
-	/* References are protected by the nfnl mutex */
+	/* Commands are serialized and references are
+	 * protected by the ip_set_ref_lock.
+	 * External systems (i.e. xt_set) must call
+	 * ip_set_put|get_nfnl_* functions, that way we
+	 * can safely check references here.
+	 *
+	 * list:set timer can only decrement the reference
+	 * counter, so if it's already zero, we can proceed
+	 * without holding the lock.
+	 */
+	read_lock_bh(&ip_set_ref_lock);
 	if (!attr[IPSET_ATTR_SETNAME]) {
 	if (!attr[IPSET_ATTR_SETNAME]) {
 		for (i = 0; i < ip_set_max; i++) {
 		for (i = 0; i < ip_set_max; i++) {
-			if (ip_set_list[i] != NULL &&
-			    (atomic_read(&ip_set_list[i]->ref)))
-				return -IPSET_ERR_BUSY;
+			if (ip_set_list[i] != NULL && ip_set_list[i]->ref) {
+				ret = IPSET_ERR_BUSY;
+				goto out;
+			}
 		}
 		}
+		read_unlock_bh(&ip_set_ref_lock);
 		for (i = 0; i < ip_set_max; i++) {
 		for (i = 0; i < ip_set_max; i++) {
 			if (ip_set_list[i] != NULL)
 			if (ip_set_list[i] != NULL)
 				ip_set_destroy_set(i);
 				ip_set_destroy_set(i);
 		}
 		}
 	} else {
 	} else {
 		i = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME]));
 		i = find_set_id(nla_data(attr[IPSET_ATTR_SETNAME]));
-		if (i == IPSET_INVALID_ID)
-			return -ENOENT;
-		else if (atomic_read(&ip_set_list[i]->ref))
-			return -IPSET_ERR_BUSY;
+		if (i == IPSET_INVALID_ID) {
+			ret = -ENOENT;
+			goto out;
+		} else if (ip_set_list[i]->ref) {
+			ret = -IPSET_ERR_BUSY;
+			goto out;
+		}
+		read_unlock_bh(&ip_set_ref_lock);
 
 
 		ip_set_destroy_set(i);
 		ip_set_destroy_set(i);
 	}
 	}
 	return 0;
 	return 0;
+out:
+	read_unlock_bh(&ip_set_ref_lock);
+	return ret;
 }
 }
 
 
 /* Flush sets */
 /* Flush sets */
@@ -834,6 +851,7 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb,
 	struct ip_set *set;
 	struct ip_set *set;
 	const char *name2;
 	const char *name2;
 	ip_set_id_t i;
 	ip_set_id_t i;
+	int ret = 0;
 
 
 	if (unlikely(protocol_failed(attr) ||
 	if (unlikely(protocol_failed(attr) ||
 		     attr[IPSET_ATTR_SETNAME] == NULL ||
 		     attr[IPSET_ATTR_SETNAME] == NULL ||
@@ -843,25 +861,33 @@ ip_set_rename(struct sock *ctnl, struct sk_buff *skb,
 	set = find_set(nla_data(attr[IPSET_ATTR_SETNAME]));
 	set = find_set(nla_data(attr[IPSET_ATTR_SETNAME]));
 	if (set == NULL)
 	if (set == NULL)
 		return -ENOENT;
 		return -ENOENT;
-	if (atomic_read(&set->ref) != 0)
-		return -IPSET_ERR_REFERENCED;
+
+	read_lock_bh(&ip_set_ref_lock);
+	if (set->ref != 0) {
+		ret = -IPSET_ERR_REFERENCED;
+		goto out;
+	}
 
 
 	name2 = nla_data(attr[IPSET_ATTR_SETNAME2]);
 	name2 = nla_data(attr[IPSET_ATTR_SETNAME2]);
 	for (i = 0; i < ip_set_max; i++) {
 	for (i = 0; i < ip_set_max; i++) {
 		if (ip_set_list[i] != NULL &&
 		if (ip_set_list[i] != NULL &&
-		    STREQ(ip_set_list[i]->name, name2))
-			return -IPSET_ERR_EXIST_SETNAME2;
+		    STREQ(ip_set_list[i]->name, name2)) {
+			ret = -IPSET_ERR_EXIST_SETNAME2;
+			goto out;
+		}
 	}
 	}
 	strncpy(set->name, name2, IPSET_MAXNAMELEN);
 	strncpy(set->name, name2, IPSET_MAXNAMELEN);
 
 
-	return 0;
+out:
+	read_unlock_bh(&ip_set_ref_lock);
+	return ret;
 }
 }
 
 
 /* Swap two sets so that name/index points to the other.
 /* Swap two sets so that name/index points to the other.
  * References and set names are also swapped.
  * References and set names are also swapped.
  *
  *
- * We are protected by the nfnl mutex and references are
- * manipulated only by holding the mutex. The kernel interfaces
+ * The commands are serialized by the nfnl mutex and references are
+ * protected by the ip_set_ref_lock. The kernel interfaces
  * do not hold the mutex but the pointer settings are atomic
  * do not hold the mutex but the pointer settings are atomic
  * so the ip_set_list always contains valid pointers to the sets.
  * so the ip_set_list always contains valid pointers to the sets.
  */
  */
@@ -874,7 +900,6 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb,
 	struct ip_set *from, *to;
 	struct ip_set *from, *to;
 	ip_set_id_t from_id, to_id;
 	ip_set_id_t from_id, to_id;
 	char from_name[IPSET_MAXNAMELEN];
 	char from_name[IPSET_MAXNAMELEN];
-	u32 from_ref;
 
 
 	if (unlikely(protocol_failed(attr) ||
 	if (unlikely(protocol_failed(attr) ||
 		     attr[IPSET_ATTR_SETNAME] == NULL ||
 		     attr[IPSET_ATTR_SETNAME] == NULL ||
@@ -899,17 +924,15 @@ ip_set_swap(struct sock *ctnl, struct sk_buff *skb,
 	      from->type->family == to->type->family))
 	      from->type->family == to->type->family))
 		return -IPSET_ERR_TYPE_MISMATCH;
 		return -IPSET_ERR_TYPE_MISMATCH;
 
 
-	/* No magic here: ref munging protected by the nfnl_lock */
 	strncpy(from_name, from->name, IPSET_MAXNAMELEN);
 	strncpy(from_name, from->name, IPSET_MAXNAMELEN);
-	from_ref = atomic_read(&from->ref);
-
 	strncpy(from->name, to->name, IPSET_MAXNAMELEN);
 	strncpy(from->name, to->name, IPSET_MAXNAMELEN);
-	atomic_set(&from->ref, atomic_read(&to->ref));
 	strncpy(to->name, from_name, IPSET_MAXNAMELEN);
 	strncpy(to->name, from_name, IPSET_MAXNAMELEN);
-	atomic_set(&to->ref, from_ref);
 
 
+	write_lock_bh(&ip_set_ref_lock);
+	swap(from->ref, to->ref);
 	ip_set_list[from_id] = to;
 	ip_set_list[from_id] = to;
 	ip_set_list[to_id] = from;
 	ip_set_list[to_id] = from;
+	write_unlock_bh(&ip_set_ref_lock);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -926,7 +949,7 @@ ip_set_dump_done(struct netlink_callback *cb)
 {
 {
 	if (cb->args[2]) {
 	if (cb->args[2]) {
 		pr_debug("release set %s\n", ip_set_list[cb->args[1]]->name);
 		pr_debug("release set %s\n", ip_set_list[cb->args[1]]->name);
-		__ip_set_put((ip_set_id_t) cb->args[1]);
+		ip_set_put_byindex((ip_set_id_t) cb->args[1]);
 	}
 	}
 	return 0;
 	return 0;
 }
 }
@@ -1068,7 +1091,7 @@ release_refcount:
 	/* If there was an error or set is done, release set */
 	/* If there was an error or set is done, release set */
 	if (ret || !cb->args[2]) {
 	if (ret || !cb->args[2]) {
 		pr_debug("release set %s\n", ip_set_list[index]->name);
 		pr_debug("release set %s\n", ip_set_list[index]->name);
-		__ip_set_put(index);
+		ip_set_put_byindex(index);
 	}
 	}
 
 
 	/* If we dump all sets, continue with dumping last ones */
 	/* If we dump all sets, continue with dumping last ones */

+ 23 - 30
net/netfilter/ipset/ip_set_list_set.c

@@ -43,14 +43,19 @@ struct list_set {
 static inline struct set_elem *
 static inline struct set_elem *
 list_set_elem(const struct list_set *map, u32 id)
 list_set_elem(const struct list_set *map, u32 id)
 {
 {
-	return (struct set_elem *)((char *)map->members + id * map->dsize);
+	return (struct set_elem *)((void *)map->members + id * map->dsize);
+}
+
+static inline struct set_telem *
+list_set_telem(const struct list_set *map, u32 id)
+{
+	return (struct set_telem *)((void *)map->members + id * map->dsize);
 }
 }
 
 
 static inline bool
 static inline bool
 list_set_timeout(const struct list_set *map, u32 id)
 list_set_timeout(const struct list_set *map, u32 id)
 {
 {
-	const struct set_telem *elem =
-		(const struct set_telem *) list_set_elem(map, id);
+	const struct set_telem *elem = list_set_telem(map, id);
 
 
 	return ip_set_timeout_test(elem->timeout);
 	return ip_set_timeout_test(elem->timeout);
 }
 }
@@ -58,19 +63,11 @@ list_set_timeout(const struct list_set *map, u32 id)
 static inline bool
 static inline bool
 list_set_expired(const struct list_set *map, u32 id)
 list_set_expired(const struct list_set *map, u32 id)
 {
 {
-	const struct set_telem *elem =
-		(const struct set_telem *) list_set_elem(map, id);
+	const struct set_telem *elem = list_set_telem(map, id);
 
 
 	return ip_set_timeout_expired(elem->timeout);
 	return ip_set_timeout_expired(elem->timeout);
 }
 }
 
 
-static inline int
-list_set_exist(const struct set_telem *elem)
-{
-	return elem->id != IPSET_INVALID_ID &&
-	       !ip_set_timeout_expired(elem->timeout);
-}
-
 /* Set list without and with timeout */
 /* Set list without and with timeout */
 
 
 static int
 static int
@@ -146,11 +143,11 @@ list_elem_tadd(struct list_set *map, u32 i, ip_set_id_t id,
 	struct set_telem *e;
 	struct set_telem *e;
 
 
 	for (; i < map->size; i++) {
 	for (; i < map->size; i++) {
-		e = (struct set_telem *)list_set_elem(map, i);
+		e = list_set_telem(map, i);
 		swap(e->id, id);
 		swap(e->id, id);
+		swap(e->timeout, timeout);
 		if (e->id == IPSET_INVALID_ID)
 		if (e->id == IPSET_INVALID_ID)
 			break;
 			break;
-		swap(e->timeout, timeout);
 	}
 	}
 }
 }
 
 
@@ -164,7 +161,7 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id,
 		/* Last element replaced: e.g. add new,before,last */
 		/* Last element replaced: e.g. add new,before,last */
 		ip_set_put_byindex(e->id);
 		ip_set_put_byindex(e->id);
 	if (with_timeout(map->timeout))
 	if (with_timeout(map->timeout))
-		list_elem_tadd(map, i, id, timeout);
+		list_elem_tadd(map, i, id, ip_set_timeout_set(timeout));
 	else
 	else
 		list_elem_add(map, i, id);
 		list_elem_add(map, i, id);
 
 
@@ -172,11 +169,11 @@ list_set_add(struct list_set *map, u32 i, ip_set_id_t id,
 }
 }
 
 
 static int
 static int
-list_set_del(struct list_set *map, ip_set_id_t id, u32 i)
+list_set_del(struct list_set *map, u32 i)
 {
 {
 	struct set_elem *a = list_set_elem(map, i), *b;
 	struct set_elem *a = list_set_elem(map, i), *b;
 
 
-	ip_set_put_byindex(id);
+	ip_set_put_byindex(a->id);
 
 
 	for (; i < map->size - 1; i++) {
 	for (; i < map->size - 1; i++) {
 		b = list_set_elem(map, i + 1);
 		b = list_set_elem(map, i + 1);
@@ -308,11 +305,11 @@ list_set_uadt(struct ip_set *set, struct nlattr *tb[],
 				 (before == 0 ||
 				 (before == 0 ||
 				  (before > 0 &&
 				  (before > 0 &&
 				   next_id_eq(map, i, refid))))
 				   next_id_eq(map, i, refid))))
-				ret = list_set_del(map, id, i);
+				ret = list_set_del(map, i);
 			else if (before < 0 &&
 			else if (before < 0 &&
 				 elem->id == refid &&
 				 elem->id == refid &&
 				 next_id_eq(map, i, id))
 				 next_id_eq(map, i, id))
-				ret = list_set_del(map, id, i + 1);
+				ret = list_set_del(map, i + 1);
 		}
 		}
 		break;
 		break;
 	default:
 	default:
@@ -369,8 +366,7 @@ list_set_head(struct ip_set *set, struct sk_buff *skb)
 	NLA_PUT_NET32(skb, IPSET_ATTR_SIZE, htonl(map->size));
 	NLA_PUT_NET32(skb, IPSET_ATTR_SIZE, htonl(map->size));
 	if (with_timeout(map->timeout))
 	if (with_timeout(map->timeout))
 		NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout));
 		NLA_PUT_NET32(skb, IPSET_ATTR_TIMEOUT, htonl(map->timeout));
-	NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES,
-		      htonl(atomic_read(&set->ref) - 1));
+	NLA_PUT_NET32(skb, IPSET_ATTR_REFERENCES, htonl(set->ref - 1));
 	NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
 	NLA_PUT_NET32(skb, IPSET_ATTR_MEMSIZE,
 		      htonl(sizeof(*map) + map->size * map->dsize));
 		      htonl(sizeof(*map) + map->size * map->dsize));
 	ipset_nest_end(skb, nested);
 	ipset_nest_end(skb, nested);
@@ -461,16 +457,13 @@ list_set_gc(unsigned long ul_set)
 	struct set_telem *e;
 	struct set_telem *e;
 	u32 i;
 	u32 i;
 
 
-	/* We run parallel with other readers (test element)
-	 * but adding/deleting new entries is locked out */
-	read_lock_bh(&set->lock);
-	for (i = map->size - 1; i >= 0; i--) {
-		e = (struct set_telem *) list_set_elem(map, i);
-		if (e->id != IPSET_INVALID_ID &&
-		    list_set_expired(map, i))
-			list_set_del(map, e->id, i);
+	write_lock_bh(&set->lock);
+	for (i = 0; i < map->size; i++) {
+		e = list_set_telem(map, i);
+		if (e->id != IPSET_INVALID_ID && list_set_expired(map, i))
+			list_set_del(map, i);
 	}
 	}
-	read_unlock_bh(&set->lock);
+	write_unlock_bh(&set->lock);
 
 
 	map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
 	map->gc.expires = jiffies + IPSET_GC_PERIOD(map->timeout) * HZ;
 	add_timer(&map->gc);
 	add_timer(&map->gc);

+ 1 - 1
net/netfilter/ipvs/ip_vs_ctl.c

@@ -3120,7 +3120,7 @@ nla_put_failure:
 static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
 static int ip_vs_genl_dump_daemons(struct sk_buff *skb,
 				   struct netlink_callback *cb)
 				   struct netlink_callback *cb)
 {
 {
-	struct net *net = skb_net(skb);
+	struct net *net = skb_sknet(skb);
 	struct netns_ipvs *ipvs = net_ipvs(net);
 	struct netns_ipvs *ipvs = net_ipvs(net);
 
 
 	mutex_lock(&__ip_vs_mutex);
 	mutex_lock(&__ip_vs_mutex);

+ 1 - 1
net/netfilter/nf_conntrack_h323_asn1.c

@@ -631,7 +631,7 @@ static int decode_seqof(bitstr_t *bs, const struct field_t *f,
 		CHECK_BOUND(bs, 2);
 		CHECK_BOUND(bs, 2);
 		count = *bs->cur++;
 		count = *bs->cur++;
 		count <<= 8;
 		count <<= 8;
-		count = *bs->cur++;
+		count += *bs->cur++;
 		break;
 		break;
 	case SEMI:
 	case SEMI:
 		BYTE_ALIGN(bs);
 		BYTE_ALIGN(bs);

+ 8 - 8
net/netfilter/nf_conntrack_h323_main.c

@@ -731,10 +731,10 @@ static int callforward_do_filter(const union nf_inet_addr *src,
 
 
 		memset(&fl2, 0, sizeof(fl2));
 		memset(&fl2, 0, sizeof(fl2));
 		fl2.daddr = dst->ip;
 		fl2.daddr = dst->ip;
-		if (!afinfo->route((struct dst_entry **)&rt1,
-				   flowi4_to_flowi(&fl1))) {
-			if (!afinfo->route((struct dst_entry **)&rt2,
-					   flowi4_to_flowi(&fl2))) {
+		if (!afinfo->route(&init_net, (struct dst_entry **)&rt1,
+				   flowi4_to_flowi(&fl1), false)) {
+			if (!afinfo->route(&init_net, (struct dst_entry **)&rt2,
+					   flowi4_to_flowi(&fl2), false)) {
 				if (rt1->rt_gateway == rt2->rt_gateway &&
 				if (rt1->rt_gateway == rt2->rt_gateway &&
 				    rt1->dst.dev  == rt2->dst.dev)
 				    rt1->dst.dev  == rt2->dst.dev)
 					ret = 1;
 					ret = 1;
@@ -755,10 +755,10 @@ static int callforward_do_filter(const union nf_inet_addr *src,
 
 
 		memset(&fl2, 0, sizeof(fl2));
 		memset(&fl2, 0, sizeof(fl2));
 		ipv6_addr_copy(&fl2.daddr, &dst->in6);
 		ipv6_addr_copy(&fl2.daddr, &dst->in6);
-		if (!afinfo->route((struct dst_entry **)&rt1,
-				   flowi6_to_flowi(&fl1))) {
-			if (!afinfo->route((struct dst_entry **)&rt2,
-					   flowi6_to_flowi(&fl2))) {
+		if (!afinfo->route(&init_net, (struct dst_entry **)&rt1,
+				   flowi6_to_flowi(&fl1), false)) {
+			if (!afinfo->route(&init_net, (struct dst_entry **)&rt2,
+					   flowi6_to_flowi(&fl2), false)) {
 				if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway,
 				if (!memcmp(&rt1->rt6i_gateway, &rt2->rt6i_gateway,
 					    sizeof(rt1->rt6i_gateway)) &&
 					    sizeof(rt1->rt6i_gateway)) &&
 				    rt1->dst.dev == rt2->dst.dev)
 				    rt1->dst.dev == rt2->dst.dev)

+ 1 - 1
net/netfilter/xt_TCPMSS.c

@@ -166,7 +166,7 @@ static u_int32_t tcpmss_reverse_mtu(const struct sk_buff *skb,
 	rcu_read_lock();
 	rcu_read_lock();
 	ai = nf_get_afinfo(family);
 	ai = nf_get_afinfo(family);
 	if (ai != NULL)
 	if (ai != NULL)
-		ai->route((struct dst_entry **)&rt, &fl);
+		ai->route(&init_net, (struct dst_entry **)&rt, &fl, false);
 	rcu_read_unlock();
 	rcu_read_unlock();
 
 
 	if (rt != NULL) {
 	if (rt != NULL) {

+ 28 - 14
net/netfilter/xt_addrtype.c

@@ -32,11 +32,32 @@ MODULE_ALIAS("ipt_addrtype");
 MODULE_ALIAS("ip6t_addrtype");
 MODULE_ALIAS("ip6t_addrtype");
 
 
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
-static u32 xt_addrtype_rt6_to_type(const struct rt6_info *rt)
+static u32 match_lookup_rt6(struct net *net, const struct net_device *dev,
+			    const struct in6_addr *addr)
 {
 {
+	const struct nf_afinfo *afinfo;
+	struct flowi6 flow;
+	struct rt6_info *rt;
 	u32 ret;
 	u32 ret;
+	int route_err;
 
 
-	if (!rt)
+	memset(&flow, 0, sizeof(flow));
+	ipv6_addr_copy(&flow.daddr, addr);
+	if (dev)
+		flow.flowi6_oif = dev->ifindex;
+
+	rcu_read_lock();
+
+	afinfo = nf_get_afinfo(NFPROTO_IPV6);
+	if (afinfo != NULL)
+		route_err = afinfo->route(net, (struct dst_entry **)&rt,
+					flowi6_to_flowi(&flow), !!dev);
+	else
+		route_err = 1;
+
+	rcu_read_unlock();
+
+	if (route_err)
 		return XT_ADDRTYPE_UNREACHABLE;
 		return XT_ADDRTYPE_UNREACHABLE;
 
 
 	if (rt->rt6i_flags & RTF_REJECT)
 	if (rt->rt6i_flags & RTF_REJECT)
@@ -48,6 +69,9 @@ static u32 xt_addrtype_rt6_to_type(const struct rt6_info *rt)
 		ret |= XT_ADDRTYPE_LOCAL;
 		ret |= XT_ADDRTYPE_LOCAL;
 	if (rt->rt6i_flags & RTF_ANYCAST)
 	if (rt->rt6i_flags & RTF_ANYCAST)
 		ret |= XT_ADDRTYPE_ANYCAST;
 		ret |= XT_ADDRTYPE_ANYCAST;
+
+
+	dst_release(&rt->dst);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -65,18 +89,8 @@ static bool match_type6(struct net *net, const struct net_device *dev,
 		return false;
 		return false;
 
 
 	if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST |
 	if ((XT_ADDRTYPE_LOCAL | XT_ADDRTYPE_ANYCAST |
-	     XT_ADDRTYPE_UNREACHABLE) & mask) {
-		struct rt6_info *rt;
-		u32 type;
-		int ifindex = dev ? dev->ifindex : 0;
-
-		rt = rt6_lookup(net, addr, NULL, ifindex, !!dev);
-
-		type = xt_addrtype_rt6_to_type(rt);
-
-		dst_release(&rt->dst);
-		return !!(mask & type);
-	}
+	     XT_ADDRTYPE_UNREACHABLE) & mask)
+		return !!(mask & match_lookup_rt6(net, dev, addr));
 	return true;
 	return true;
 }
 }
 
 

+ 1 - 1
net/netfilter/xt_conntrack.c

@@ -195,7 +195,7 @@ conntrack_mt(const struct sk_buff *skb, struct xt_action_param *par,
 		return info->match_flags & XT_CONNTRACK_STATE;
 		return info->match_flags & XT_CONNTRACK_STATE;
 	if ((info->match_flags & XT_CONNTRACK_DIRECTION) &&
 	if ((info->match_flags & XT_CONNTRACK_DIRECTION) &&
 	    (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^
 	    (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) ^
-	    !!(info->invert_flags & XT_CONNTRACK_DIRECTION))
+	    !(info->invert_flags & XT_CONNTRACK_DIRECTION))
 		return false;
 		return false;
 
 
 	if (info->match_flags & XT_CONNTRACK_ORIGSRC)
 	if (info->match_flags & XT_CONNTRACK_ORIGSRC)