Răsfoiți Sursa

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

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net: (73 commits)
  netfilter: Remove ADVANCED dependency from NF_CONNTRACK_NETBIOS_NS
  ipv4: flush route cache after change accept_local
  sch_red: fix red_change
  Revert "udp: remove redundant variable"
  bridge: master device stuck in no-carrier state forever when in user-stp mode
  ipv4: Perform peer validation on cached route lookup.
  net/core: fix rollback handler in register_netdevice_notifier
  sch_red: fix red_calc_qavg_from_idle_time
  bonding: only use primary address for ARP
  ipv4: fix lockdep splat in rt_cache_seq_show
  sch_teql: fix lockdep splat
  net: fec: Select the FEC driver by default for i.MX SoCs
  isdn: avoid copying too long drvid
  isdn: make sure strings are null terminated
  netlabel: Fix build problems when IPv6 is not enabled
  sctp: better integer overflow check in sctp_auth_create_key()
  sctp: integer overflow in sctp_auth_create_key()
  ipv6: Set mcast_hops to IPV6_DEFAULT_MCASTHOPS when -1 was given.
  net: Fix corruption in /proc/*/net/dev_mcast
  mac80211: fix race between the AGG SM and the Tx data path
  ...
Linus Torvalds 13 ani în urmă
părinte
comite
5983fe2b29
77 a modificat fișierele cu 589 adăugiri și 280 ștergeri
  1. 6 0
      drivers/isdn/divert/divert_procfs.c
  2. 3 0
      drivers/isdn/i4l/isdn_net.c
  3. 1 1
      drivers/net/arcnet/Kconfig
  4. 6 27
      drivers/net/bonding/bond_main.c
  5. 0 1
      drivers/net/can/sja1000/peak_pci.c
  6. 1 1
      drivers/net/ethernet/broadcom/b44.c
  7. 38 1
      drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c
  8. 1 0
      drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h
  9. 1 1
      drivers/net/ethernet/davicom/dm9000.c
  10. 1 0
      drivers/net/ethernet/freescale/Kconfig
  11. 2 2
      drivers/net/ethernet/ibm/ehea/ehea.h
  12. 4 2
      drivers/net/ethernet/ibm/ehea/ehea_main.c
  13. 1 1
      drivers/net/ethernet/ibm/iseries_veth.c
  14. 110 3
      drivers/net/ethernet/jme.c
  15. 19 0
      drivers/net/ethernet/jme.h
  16. 3 5
      drivers/net/ethernet/qlogic/qlge/qlge.h
  17. 9 5
      drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
  18. 1 1
      drivers/net/phy/Kconfig
  19. 3 2
      drivers/net/wireless/p54/p54spi.c
  20. 1 1
      drivers/net/wireless/prism54/isl_ioctl.c
  21. 1 1
      drivers/net/wireless/rt2x00/rt2800lib.c
  22. 9 8
      drivers/net/wireless/rtlwifi/ps.c
  23. 1 1
      drivers/net/xen-netback/netback.c
  24. 2 0
      include/linux/netdevice.h
  25. 3 3
      include/linux/pkt_sched.h
  26. 1 6
      include/net/dst.h
  27. 1 1
      include/net/dst_ops.h
  28. 2 0
      include/net/inet_sock.h
  29. 1 0
      include/net/inetpeer.h
  30. 10 9
      include/net/netfilter/nf_conntrack_ecache.h
  31. 2 0
      include/net/netns/conntrack.h
  32. 6 9
      include/net/red.h
  33. 2 2
      include/net/route.h
  34. 6 0
      net/bridge/br_netlink.c
  35. 14 15
      net/bridge/br_stp.c
  36. 6 5
      net/caif/cffrml.c
  37. 8 1
      net/core/dev.c
  38. 1 2
      net/core/dev_addr_lists.c
  39. 4 1
      net/core/neighbour.c
  40. 1 1
      net/core/skbuff.c
  41. 1 0
      net/dccp/ipv4.c
  42. 6 4
      net/decnet/dn_route.c
  43. 5 12
      net/decnet/dn_timer.c
  44. 5 0
      net/ipv4/devinet.c
  45. 2 1
      net/ipv4/igmp.c
  46. 9 5
      net/ipv4/inet_diag.c
  47. 1 1
      net/ipv4/ip_forward.c
  48. 3 2
      net/ipv4/ip_options.c
  49. 2 1
      net/ipv4/netfilter.c
  50. 0 1
      net/ipv4/netfilter/Kconfig
  51. 49 18
      net/ipv4/route.c
  52. 8 7
      net/ipv4/udp.c
  53. 1 1
      net/ipv6/inet6_connection_sock.c
  54. 1 1
      net/ipv6/ipv6_sockglue.c
  55. 1 1
      net/ipv6/ndisc.c
  56. 0 1
      net/ipv6/netfilter/Kconfig
  57. 14 7
      net/ipv6/route.c
  58. 7 6
      net/ipv6/tcp_ipv6.c
  59. 8 7
      net/ipv6/udp.c
  60. 1 1
      net/l2tp/l2tp_core.c
  61. 39 3
      net/mac80211/agg-tx.c
  62. 2 2
      net/mac80211/debugfs_sta.c
  63. 4 4
      net/mac80211/status.c
  64. 0 2
      net/netfilter/Kconfig
  65. 1 1
      net/netfilter/ipset/ip_set_hash_ipport.c
  66. 1 1
      net/netfilter/ipset/ip_set_hash_ipportip.c
  67. 1 1
      net/netfilter/ipset/ip_set_hash_ipportnet.c
  68. 18 19
      net/netfilter/nf_conntrack_ecache.c
  69. 52 21
      net/netfilter/nf_conntrack_netlink.c
  70. 16 10
      net/netlabel/netlabel_kapi.c
  71. 2 2
      net/sched/sch_red.c
  72. 20 11
      net/sched/sch_teql.c
  73. 1 1
      net/sctp/auth.c
  74. 4 0
      net/unix/af_unix.c
  75. 2 2
      net/wireless/nl80211.c
  76. 4 0
      net/wireless/reg.c
  77. 6 4
      net/xfrm/xfrm_policy.c

+ 6 - 0
drivers/isdn/divert/divert_procfs.c

@@ -242,6 +242,12 @@ static int isdn_divert_ioctl_unlocked(struct file *file, uint cmd, ulong arg)
 		case IIOCDOCFINT:
 		case IIOCDOCFINT:
 			if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid))
 			if (!divert_if.drv_to_name(dioctl.cf_ctrl.drvid))
 				return (-EINVAL);	/* invalid driver */
 				return (-EINVAL);	/* invalid driver */
+			if (strnlen(dioctl.cf_ctrl.msn, sizeof(dioctl.cf_ctrl.msn)) ==
+					sizeof(dioctl.cf_ctrl.msn))
+				return -EINVAL;
+			if (strnlen(dioctl.cf_ctrl.fwd_nr, sizeof(dioctl.cf_ctrl.fwd_nr)) ==
+					sizeof(dioctl.cf_ctrl.fwd_nr))
+				return -EINVAL;
 			if ((i = cf_command(dioctl.cf_ctrl.drvid,
 			if ((i = cf_command(dioctl.cf_ctrl.drvid,
 					    (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2,
 					    (cmd == IIOCDOCFACT) ? 1 : (cmd == IIOCDOCFDIS) ? 0 : 2,
 					    dioctl.cf_ctrl.cfproc,
 					    dioctl.cf_ctrl.cfproc,

+ 3 - 0
drivers/isdn/i4l/isdn_net.c

@@ -2756,6 +2756,9 @@ isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
 			char *c,
 			char *c,
 			*e;
 			*e;
 
 
+			if (strnlen(cfg->drvid, sizeof(cfg->drvid)) ==
+					sizeof(cfg->drvid))
+				return -EINVAL;
 			drvidx = -1;
 			drvidx = -1;
 			chidx = -1;
 			chidx = -1;
 			strcpy(drvid, cfg->drvid);
 			strcpy(drvid, cfg->drvid);

+ 1 - 1
drivers/net/arcnet/Kconfig

@@ -4,7 +4,7 @@
 
 
 menuconfig ARCNET
 menuconfig ARCNET
 	depends on NETDEVICES && (ISA || PCI || PCMCIA)
 	depends on NETDEVICES && (ISA || PCI || PCMCIA)
-	bool "ARCnet support"
+	tristate "ARCnet support"
 	---help---
 	---help---
 	  If you have a network card of this type, say Y and check out the
 	  If you have a network card of this type, say Y and check out the
 	  (arguably) beautiful poetry in
 	  (arguably) beautiful poetry in

+ 6 - 27
drivers/net/bonding/bond_main.c

@@ -2553,30 +2553,6 @@ re_arm:
 	}
 	}
 }
 }
 
 
-static __be32 bond_glean_dev_ip(struct net_device *dev)
-{
-	struct in_device *idev;
-	struct in_ifaddr *ifa;
-	__be32 addr = 0;
-
-	if (!dev)
-		return 0;
-
-	rcu_read_lock();
-	idev = __in_dev_get_rcu(dev);
-	if (!idev)
-		goto out;
-
-	ifa = idev->ifa_list;
-	if (!ifa)
-		goto out;
-
-	addr = ifa->ifa_local;
-out:
-	rcu_read_unlock();
-	return addr;
-}
-
 static int bond_has_this_ip(struct bonding *bond, __be32 ip)
 static int bond_has_this_ip(struct bonding *bond, __be32 ip)
 {
 {
 	struct vlan_entry *vlan;
 	struct vlan_entry *vlan;
@@ -3322,6 +3298,10 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
 	struct bonding *bond;
 	struct bonding *bond;
 	struct vlan_entry *vlan;
 	struct vlan_entry *vlan;
 
 
+	/* we only care about primary address */
+	if(ifa->ifa_flags & IFA_F_SECONDARY)
+		return NOTIFY_DONE;
+
 	list_for_each_entry(bond, &bn->dev_list, bond_list) {
 	list_for_each_entry(bond, &bn->dev_list, bond_list) {
 		if (bond->dev == event_dev) {
 		if (bond->dev == event_dev) {
 			switch (event) {
 			switch (event) {
@@ -3329,7 +3309,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
 				bond->master_ip = ifa->ifa_local;
 				bond->master_ip = ifa->ifa_local;
 				return NOTIFY_OK;
 				return NOTIFY_OK;
 			case NETDEV_DOWN:
 			case NETDEV_DOWN:
-				bond->master_ip = bond_glean_dev_ip(bond->dev);
+				bond->master_ip = 0;
 				return NOTIFY_OK;
 				return NOTIFY_OK;
 			default:
 			default:
 				return NOTIFY_DONE;
 				return NOTIFY_DONE;
@@ -3345,8 +3325,7 @@ static int bond_inetaddr_event(struct notifier_block *this, unsigned long event,
 					vlan->vlan_ip = ifa->ifa_local;
 					vlan->vlan_ip = ifa->ifa_local;
 					return NOTIFY_OK;
 					return NOTIFY_OK;
 				case NETDEV_DOWN:
 				case NETDEV_DOWN:
-					vlan->vlan_ip =
-						bond_glean_dev_ip(vlan_dev);
+					vlan->vlan_ip = 0;
 					return NOTIFY_OK;
 					return NOTIFY_OK;
 				default:
 				default:
 					return NOTIFY_DONE;
 					return NOTIFY_DONE;

+ 0 - 1
drivers/net/can/sja1000/peak_pci.c

@@ -20,7 +20,6 @@
  */
  */
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/interrupt.h>
 #include <linux/netdevice.h>
 #include <linux/netdevice.h>

+ 1 - 1
drivers/net/ethernet/broadcom/b44.c

@@ -608,7 +608,7 @@ static void b44_tx(struct b44 *bp)
 				 skb->len,
 				 skb->len,
 				 DMA_TO_DEVICE);
 				 DMA_TO_DEVICE);
 		rp->skb = NULL;
 		rp->skb = NULL;
-		dev_kfree_skb(skb);
+		dev_kfree_skb_irq(skb);
 	}
 	}
 
 
 	bp->tx_cons = cons;
 	bp->tx_cons = cons;

+ 38 - 1
drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c

@@ -10327,6 +10327,43 @@ static int bnx2x_54618se_config_init(struct bnx2x_phy *phy,
 	return 0;
 	return 0;
 }
 }
 
 
+
+static void bnx2x_5461x_set_link_led(struct bnx2x_phy *phy,
+				       struct link_params *params, u8 mode)
+{
+	struct bnx2x *bp = params->bp;
+	u16 temp;
+
+	bnx2x_cl22_write(bp, phy,
+		MDIO_REG_GPHY_SHADOW,
+		MDIO_REG_GPHY_SHADOW_LED_SEL1);
+	bnx2x_cl22_read(bp, phy,
+		MDIO_REG_GPHY_SHADOW,
+		&temp);
+	temp &= 0xff00;
+
+	DP(NETIF_MSG_LINK, "54618x set link led (mode=%x)\n", mode);
+	switch (mode) {
+	case LED_MODE_FRONT_PANEL_OFF:
+	case LED_MODE_OFF:
+		temp |= 0x00ee;
+		break;
+	case LED_MODE_OPER:
+		temp |= 0x0001;
+		break;
+	case LED_MODE_ON:
+		temp |= 0x00ff;
+		break;
+	default:
+		break;
+	}
+	bnx2x_cl22_write(bp, phy,
+		MDIO_REG_GPHY_SHADOW,
+		MDIO_REG_GPHY_SHADOW_WR_ENA | temp);
+	return;
+}
+
+
 static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
 static void bnx2x_54618se_link_reset(struct bnx2x_phy *phy,
 				     struct link_params *params)
 				     struct link_params *params)
 {
 {
@@ -11103,7 +11140,7 @@ static struct bnx2x_phy phy_54618se = {
 	.config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
 	.config_loopback = (config_loopback_t)bnx2x_54618se_config_loopback,
 	.format_fw_ver	= (format_fw_ver_t)NULL,
 	.format_fw_ver	= (format_fw_ver_t)NULL,
 	.hw_reset	= (hw_reset_t)NULL,
 	.hw_reset	= (hw_reset_t)NULL,
-	.set_link_led	= (set_link_led_t)NULL,
+	.set_link_led	= (set_link_led_t)bnx2x_5461x_set_link_led,
 	.phy_specific_func = (phy_specific_func_t)NULL
 	.phy_specific_func = (phy_specific_func_t)NULL
 };
 };
 /*****************************************************************/
 /*****************************************************************/

+ 1 - 0
drivers/net/ethernet/broadcom/bnx2x/bnx2x_reg.h

@@ -6990,6 +6990,7 @@ Theotherbitsarereservedandshouldbezero*/
 #define MDIO_REG_INTR_MASK				0x1b
 #define MDIO_REG_INTR_MASK				0x1b
 #define MDIO_REG_INTR_MASK_LINK_STATUS			(0x1 << 1)
 #define MDIO_REG_INTR_MASK_LINK_STATUS			(0x1 << 1)
 #define MDIO_REG_GPHY_SHADOW				0x1c
 #define MDIO_REG_GPHY_SHADOW				0x1c
+#define MDIO_REG_GPHY_SHADOW_LED_SEL1			(0x0d << 10)
 #define MDIO_REG_GPHY_SHADOW_LED_SEL2			(0x0e << 10)
 #define MDIO_REG_GPHY_SHADOW_LED_SEL2			(0x0e << 10)
 #define MDIO_REG_GPHY_SHADOW_WR_ENA			(0x1 << 15)
 #define MDIO_REG_GPHY_SHADOW_WR_ENA			(0x1 << 15)
 #define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED		(0x1e << 10)
 #define MDIO_REG_GPHY_SHADOW_AUTO_DET_MED		(0x1e << 10)

+ 1 - 1
drivers/net/ethernet/davicom/dm9000.c

@@ -613,7 +613,7 @@ static int dm9000_set_wol(struct net_device *dev, struct ethtool_wolinfo *w)
 
 
 		if (!dm->wake_state)
 		if (!dm->wake_state)
 			irq_set_irq_wake(dm->irq_wake, 1);
 			irq_set_irq_wake(dm->irq_wake, 1);
-		else if (dm->wake_state & !opts)
+		else if (dm->wake_state && !opts)
 			irq_set_irq_wake(dm->irq_wake, 0);
 			irq_set_irq_wake(dm->irq_wake, 0);
 	}
 	}
 
 

+ 1 - 0
drivers/net/ethernet/freescale/Kconfig

@@ -24,6 +24,7 @@ config FEC
 	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
 	bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
 	depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \
 	depends on (M523x || M527x || M5272 || M528x || M520x || M532x || \
 		   ARCH_MXC || ARCH_MXS)
 		   ARCH_MXC || ARCH_MXS)
+	default ARCH_MXC || ARCH_MXS if ARM
 	select PHYLIB
 	select PHYLIB
 	---help---
 	---help---
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet
 	  Say Y here if you want to use the built-in 10/100 Fast ethernet

+ 2 - 2
drivers/net/ethernet/ibm/ehea/ehea.h

@@ -61,9 +61,9 @@
 #ifdef EHEA_SMALL_QUEUES
 #ifdef EHEA_SMALL_QUEUES
 #define EHEA_MAX_CQE_COUNT      1023
 #define EHEA_MAX_CQE_COUNT      1023
 #define EHEA_DEF_ENTRIES_SQ     1023
 #define EHEA_DEF_ENTRIES_SQ     1023
-#define EHEA_DEF_ENTRIES_RQ1    4095
+#define EHEA_DEF_ENTRIES_RQ1    1023
 #define EHEA_DEF_ENTRIES_RQ2    1023
 #define EHEA_DEF_ENTRIES_RQ2    1023
-#define EHEA_DEF_ENTRIES_RQ3    1023
+#define EHEA_DEF_ENTRIES_RQ3    511
 #else
 #else
 #define EHEA_MAX_CQE_COUNT      4080
 #define EHEA_MAX_CQE_COUNT      4080
 #define EHEA_DEF_ENTRIES_SQ     4080
 #define EHEA_DEF_ENTRIES_SQ     4080

+ 4 - 2
drivers/net/ethernet/ibm/ehea/ehea_main.c

@@ -371,7 +371,8 @@ static void ehea_update_stats(struct work_struct *work)
 out_herr:
 out_herr:
 	free_page((unsigned long)cb2);
 	free_page((unsigned long)cb2);
 resched:
 resched:
-	schedule_delayed_work(&port->stats_work, msecs_to_jiffies(1000));
+	schedule_delayed_work(&port->stats_work,
+			      round_jiffies_relative(msecs_to_jiffies(1000)));
 }
 }
 
 
 static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
 static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
@@ -2434,7 +2435,8 @@ static int ehea_open(struct net_device *dev)
 	}
 	}
 
 
 	mutex_unlock(&port->port_lock);
 	mutex_unlock(&port->port_lock);
-	schedule_delayed_work(&port->stats_work, msecs_to_jiffies(1000));
+	schedule_delayed_work(&port->stats_work,
+			      round_jiffies_relative(msecs_to_jiffies(1000)));
 
 
 	return ret;
 	return ret;
 }
 }

+ 1 - 1
drivers/net/ethernet/ibm/iseries_veth.c

@@ -1421,7 +1421,7 @@ static void veth_receive(struct veth_lpar_connection *cnx,
 
 
 		/* FIXME: do we need this? */
 		/* FIXME: do we need this? */
 		memset(local_list, 0, sizeof(local_list));
 		memset(local_list, 0, sizeof(local_list));
-		memset(remote_list, 0, sizeof(VETH_MAX_FRAMES_PER_MSG));
+		memset(remote_list, 0, sizeof(remote_list));
 
 
 		/* a 0 address marks the end of the valid entries */
 		/* a 0 address marks the end of the valid entries */
 		if (senddata->addr[startchunk] == 0)
 		if (senddata->addr[startchunk] == 0)

+ 110 - 3
drivers/net/ethernet/jme.c

@@ -1744,6 +1744,112 @@ jme_phy_off(struct jme_adapter *jme)
 		jme_new_phy_off(jme);
 		jme_new_phy_off(jme);
 }
 }
 
 
+static int
+jme_phy_specreg_read(struct jme_adapter *jme, u32 specreg)
+{
+	u32 phy_addr;
+
+	phy_addr = JM_PHY_SPEC_REG_READ | specreg;
+	jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_ADDR_REG,
+			phy_addr);
+	return jme_mdio_read(jme->dev, jme->mii_if.phy_id,
+			JM_PHY_SPEC_DATA_REG);
+}
+
+static void
+jme_phy_specreg_write(struct jme_adapter *jme, u32 ext_reg, u32 phy_data)
+{
+	u32 phy_addr;
+
+	phy_addr = JM_PHY_SPEC_REG_WRITE | ext_reg;
+	jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_DATA_REG,
+			phy_data);
+	jme_mdio_write(jme->dev, jme->mii_if.phy_id, JM_PHY_SPEC_ADDR_REG,
+			phy_addr);
+}
+
+static int
+jme_phy_calibration(struct jme_adapter *jme)
+{
+	u32 ctrl1000, phy_data;
+
+	jme_phy_off(jme);
+	jme_phy_on(jme);
+	/*  Enabel PHY test mode 1 */
+	ctrl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000);
+	ctrl1000 &= ~PHY_GAD_TEST_MODE_MSK;
+	ctrl1000 |= PHY_GAD_TEST_MODE_1;
+	jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, ctrl1000);
+
+	phy_data = jme_phy_specreg_read(jme, JM_PHY_EXT_COMM_2_REG);
+	phy_data &= ~JM_PHY_EXT_COMM_2_CALI_MODE_0;
+	phy_data |= JM_PHY_EXT_COMM_2_CALI_LATCH |
+			JM_PHY_EXT_COMM_2_CALI_ENABLE;
+	jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_2_REG, phy_data);
+	msleep(20);
+	phy_data = jme_phy_specreg_read(jme, JM_PHY_EXT_COMM_2_REG);
+	phy_data &= ~(JM_PHY_EXT_COMM_2_CALI_ENABLE |
+			JM_PHY_EXT_COMM_2_CALI_MODE_0 |
+			JM_PHY_EXT_COMM_2_CALI_LATCH);
+	jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_2_REG, phy_data);
+
+	/*  Disable PHY test mode */
+	ctrl1000 = jme_mdio_read(jme->dev, jme->mii_if.phy_id, MII_CTRL1000);
+	ctrl1000 &= ~PHY_GAD_TEST_MODE_MSK;
+	jme_mdio_write(jme->dev, jme->mii_if.phy_id, MII_CTRL1000, ctrl1000);
+	return 0;
+}
+
+static int
+jme_phy_setEA(struct jme_adapter *jme)
+{
+	u32 phy_comm0 = 0, phy_comm1 = 0;
+	u8 nic_ctrl;
+
+	pci_read_config_byte(jme->pdev, PCI_PRIV_SHARE_NICCTRL, &nic_ctrl);
+	if ((nic_ctrl & 0x3) == JME_FLAG_PHYEA_ENABLE)
+		return 0;
+
+	switch (jme->pdev->device) {
+	case PCI_DEVICE_ID_JMICRON_JMC250:
+		if (((jme->chip_main_rev == 5) &&
+			((jme->chip_sub_rev == 0) || (jme->chip_sub_rev == 1) ||
+			(jme->chip_sub_rev == 3))) ||
+			(jme->chip_main_rev >= 6)) {
+			phy_comm0 = 0x008A;
+			phy_comm1 = 0x4109;
+		}
+		if ((jme->chip_main_rev == 3) &&
+			((jme->chip_sub_rev == 1) || (jme->chip_sub_rev == 2)))
+			phy_comm0 = 0xE088;
+		break;
+	case PCI_DEVICE_ID_JMICRON_JMC260:
+		if (((jme->chip_main_rev == 5) &&
+			((jme->chip_sub_rev == 0) || (jme->chip_sub_rev == 1) ||
+			(jme->chip_sub_rev == 3))) ||
+			(jme->chip_main_rev >= 6)) {
+			phy_comm0 = 0x008A;
+			phy_comm1 = 0x4109;
+		}
+		if ((jme->chip_main_rev == 3) &&
+			((jme->chip_sub_rev == 1) || (jme->chip_sub_rev == 2)))
+			phy_comm0 = 0xE088;
+		if ((jme->chip_main_rev == 2) && (jme->chip_sub_rev == 0))
+			phy_comm0 = 0x608A;
+		if ((jme->chip_main_rev == 2) && (jme->chip_sub_rev == 2))
+			phy_comm0 = 0x408A;
+		break;
+	default:
+		return -ENODEV;
+	}
+	if (phy_comm0)
+		jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_0_REG, phy_comm0);
+	if (phy_comm1)
+		jme_phy_specreg_write(jme, JM_PHY_EXT_COMM_1_REG, phy_comm1);
+
+	return 0;
+}
+
 static int
 static int
 jme_open(struct net_device *netdev)
 jme_open(struct net_device *netdev)
 {
 {
@@ -1769,7 +1875,8 @@ jme_open(struct net_device *netdev)
 		jme_set_settings(netdev, &jme->old_ecmd);
 		jme_set_settings(netdev, &jme->old_ecmd);
 	else
 	else
 		jme_reset_phy_processor(jme);
 		jme_reset_phy_processor(jme);
-
+	jme_phy_calibration(jme);
+	jme_phy_setEA(jme);
 	jme_reset_link(jme);
 	jme_reset_link(jme);
 
 
 	return 0;
 	return 0;
@@ -3184,7 +3291,8 @@ jme_resume(struct device *dev)
 		jme_set_settings(netdev, &jme->old_ecmd);
 		jme_set_settings(netdev, &jme->old_ecmd);
 	else
 	else
 		jme_reset_phy_processor(jme);
 		jme_reset_phy_processor(jme);
-
+	jme_phy_calibration(jme);
+	jme_phy_setEA(jme);
 	jme_start_irq(jme);
 	jme_start_irq(jme);
 	netif_device_attach(netdev);
 	netif_device_attach(netdev);
 
 
@@ -3239,4 +3347,3 @@ MODULE_DESCRIPTION("JMicron JMC2x0 PCI Express Ethernet driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
 MODULE_VERSION(DRV_VERSION);
 MODULE_DEVICE_TABLE(pci, jme_pci_tbl);
 MODULE_DEVICE_TABLE(pci, jme_pci_tbl);
-

+ 19 - 0
drivers/net/ethernet/jme.h

@@ -760,6 +760,25 @@ enum jme_rxmcs_bits {
 				  RXMCS_CHECKSUM,
 				  RXMCS_CHECKSUM,
 };
 };
 
 
+/*	Extern PHY common register 2	*/
+
+#define PHY_GAD_TEST_MODE_1			0x00002000
+#define PHY_GAD_TEST_MODE_MSK			0x0000E000
+#define JM_PHY_SPEC_REG_READ			0x00004000
+#define JM_PHY_SPEC_REG_WRITE			0x00008000
+#define PHY_CALIBRATION_DELAY			20
+#define JM_PHY_SPEC_ADDR_REG			0x1E
+#define JM_PHY_SPEC_DATA_REG			0x1F
+
+#define JM_PHY_EXT_COMM_0_REG			0x30
+#define JM_PHY_EXT_COMM_1_REG			0x31
+#define JM_PHY_EXT_COMM_2_REG			0x32
+#define JM_PHY_EXT_COMM_2_CALI_ENABLE		0x01
+#define JM_PHY_EXT_COMM_2_CALI_MODE_0		0x02
+#define JM_PHY_EXT_COMM_2_CALI_LATCH		0x10
+#define PCI_PRIV_SHARE_NICCTRL			0xF5
+#define JME_FLAG_PHYEA_ENABLE			0x2
+
 /*
 /*
  * Wakeup Frame setup interface registers
  * Wakeup Frame setup interface registers
  */
  */

+ 3 - 5
drivers/net/ethernet/qlogic/qlge/qlge.h

@@ -58,10 +58,8 @@
 
 
 
 
 #define TX_DESC_PER_IOCB 8
 #define TX_DESC_PER_IOCB 8
-/* The maximum number of frags we handle is based
- * on PAGE_SIZE...
- */
-#if (PAGE_SHIFT == 12) || (PAGE_SHIFT == 13)	/* 4k & 8k pages */
+
+#if ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2) > 0
 #define TX_DESC_PER_OAL ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2)
 #define TX_DESC_PER_OAL ((MAX_SKB_FRAGS - TX_DESC_PER_IOCB) + 2)
 #else /* all other page sizes */
 #else /* all other page sizes */
 #define TX_DESC_PER_OAL 0
 #define TX_DESC_PER_OAL 0
@@ -1353,7 +1351,7 @@ struct tx_ring_desc {
 	struct ob_mac_iocb_req *queue_entry;
 	struct ob_mac_iocb_req *queue_entry;
 	u32 index;
 	u32 index;
 	struct oal oal;
 	struct oal oal;
-	struct map_list map[MAX_SKB_FRAGS + 1];
+	struct map_list map[MAX_SKB_FRAGS + 2];
 	int map_cnt;
 	int map_cnt;
 	struct tx_ring_desc *next;
 	struct tx_ring_desc *next;
 };
 };

+ 9 - 5
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c

@@ -781,10 +781,15 @@ static void stmmac_mmc_setup(struct stmmac_priv *priv)
 	unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
 	unsigned int mode = MMC_CNTRL_RESET_ON_READ | MMC_CNTRL_COUNTER_RESET |
 			    MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
 			    MMC_CNTRL_PRESET | MMC_CNTRL_FULL_HALF_PRESET;
 
 
-	/* Do not manage MMC IRQ (FIXME) */
+	/* Mask MMC irq, counters are managed in SW and registers
+	 * are cleared on each READ eventually. */
 	dwmac_mmc_intr_all_mask(priv->ioaddr);
 	dwmac_mmc_intr_all_mask(priv->ioaddr);
-	dwmac_mmc_ctrl(priv->ioaddr, mode);
-	memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
+
+	if (priv->dma_cap.rmon) {
+		dwmac_mmc_ctrl(priv->ioaddr, mode);
+		memset(&priv->mmc, 0, sizeof(struct stmmac_counters));
+	} else
+		pr_info(" No MAC Management Counters available");
 }
 }
 
 
 static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
 static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv)
@@ -1012,8 +1017,7 @@ static int stmmac_open(struct net_device *dev)
 	memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
 	memset(&priv->xstats, 0, sizeof(struct stmmac_extra_stats));
 	priv->xstats.threshold = tc;
 	priv->xstats.threshold = tc;
 
 
-	if (priv->dma_cap.rmon)
-		stmmac_mmc_setup(priv);
+	stmmac_mmc_setup(priv);
 
 
 	/* Start the ball rolling... */
 	/* Start the ball rolling... */
 	DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);
 	DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name);

+ 1 - 1
drivers/net/phy/Kconfig

@@ -3,7 +3,7 @@
 #
 #
 
 
 menuconfig PHYLIB
 menuconfig PHYLIB
-	bool "PHY Device support and infrastructure"
+	tristate "PHY Device support and infrastructure"
 	depends on !S390
 	depends on !S390
 	depends on NETDEVICES
 	depends on NETDEVICES
 	help
 	help

+ 3 - 2
drivers/net/wireless/p54/p54spi.c

@@ -588,8 +588,6 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
 
 
 	WARN_ON(priv->fw_state != FW_STATE_READY);
 	WARN_ON(priv->fw_state != FW_STATE_READY);
 
 
-	cancel_work_sync(&priv->work);
-
 	p54spi_power_off(priv);
 	p54spi_power_off(priv);
 	spin_lock_irqsave(&priv->tx_lock, flags);
 	spin_lock_irqsave(&priv->tx_lock, flags);
 	INIT_LIST_HEAD(&priv->tx_pending);
 	INIT_LIST_HEAD(&priv->tx_pending);
@@ -597,6 +595,8 @@ static void p54spi_op_stop(struct ieee80211_hw *dev)
 
 
 	priv->fw_state = FW_STATE_OFF;
 	priv->fw_state = FW_STATE_OFF;
 	mutex_unlock(&priv->mutex);
 	mutex_unlock(&priv->mutex);
+
+	cancel_work_sync(&priv->work);
 }
 }
 
 
 static int __devinit p54spi_probe(struct spi_device *spi)
 static int __devinit p54spi_probe(struct spi_device *spi)
@@ -656,6 +656,7 @@ static int __devinit p54spi_probe(struct spi_device *spi)
 	init_completion(&priv->fw_comp);
 	init_completion(&priv->fw_comp);
 	INIT_LIST_HEAD(&priv->tx_pending);
 	INIT_LIST_HEAD(&priv->tx_pending);
 	mutex_init(&priv->mutex);
 	mutex_init(&priv->mutex);
+	spin_lock_init(&priv->tx_lock);
 	SET_IEEE80211_DEV(hw, &spi->dev);
 	SET_IEEE80211_DEV(hw, &spi->dev);
 	priv->common.open = p54spi_op_start;
 	priv->common.open = p54spi_op_start;
 	priv->common.stop = p54spi_op_stop;
 	priv->common.stop = p54spi_op_stop;

+ 1 - 1
drivers/net/wireless/prism54/isl_ioctl.c

@@ -778,7 +778,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info,
 		dwrq->flags = 0;
 		dwrq->flags = 0;
 		dwrq->length = 0;
 		dwrq->length = 0;
 	}
 	}
-	essid->octets[essid->length] = '\0';
+	essid->octets[dwrq->length] = '\0';
 	memcpy(extra, essid->octets, dwrq->length);
 	memcpy(extra, essid->octets, dwrq->length);
 	kfree(essid);
 	kfree(essid);
 
 

+ 1 - 1
drivers/net/wireless/rt2x00/rt2800lib.c

@@ -3771,7 +3771,7 @@ static void rt2800_efuse_read(struct rt2x00_dev *rt2x00dev, unsigned int i)
 	/* Apparently the data is read from end to start */
 	/* Apparently the data is read from end to start */
 	rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, &reg);
 	rt2800_register_read_lock(rt2x00dev, EFUSE_DATA3, &reg);
 	/* The returned value is in CPU order, but eeprom is le */
 	/* The returned value is in CPU order, but eeprom is le */
-	rt2x00dev->eeprom[i] = cpu_to_le32(reg);
+	*(u32 *)&rt2x00dev->eeprom[i] = cpu_to_le32(reg);
 	rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, &reg);
 	rt2800_register_read_lock(rt2x00dev, EFUSE_DATA2, &reg);
 	*(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg);
 	*(u32 *)&rt2x00dev->eeprom[i + 2] = cpu_to_le32(reg);
 	rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, &reg);
 	rt2800_register_read_lock(rt2x00dev, EFUSE_DATA1, &reg);

+ 9 - 8
drivers/net/wireless/rtlwifi/ps.c

@@ -395,7 +395,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
 	if (mac->link_state != MAC80211_LINKED)
 	if (mac->link_state != MAC80211_LINKED)
 		return;
 		return;
 
 
-	spin_lock(&rtlpriv->locks.lps_lock);
+	spin_lock_irq(&rtlpriv->locks.lps_lock);
 
 
 	/* Idle for a while if we connect to AP a while ago. */
 	/* Idle for a while if we connect to AP a while ago. */
 	if (mac->cnt_after_linked >= 2) {
 	if (mac->cnt_after_linked >= 2) {
@@ -407,7 +407,7 @@ void rtl_lps_enter(struct ieee80211_hw *hw)
 		}
 		}
 	}
 	}
 
 
-	spin_unlock(&rtlpriv->locks.lps_lock);
+	spin_unlock_irq(&rtlpriv->locks.lps_lock);
 }
 }
 
 
 /*Leave the leisure power save mode.*/
 /*Leave the leisure power save mode.*/
@@ -416,8 +416,9 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+	unsigned long flags;
 
 
-	spin_lock(&rtlpriv->locks.lps_lock);
+	spin_lock_irqsave(&rtlpriv->locks.lps_lock, flags);
 
 
 	if (ppsc->fwctrl_lps) {
 	if (ppsc->fwctrl_lps) {
 		if (ppsc->dot11_psmode != EACTIVE) {
 		if (ppsc->dot11_psmode != EACTIVE) {
@@ -438,7 +439,7 @@ void rtl_lps_leave(struct ieee80211_hw *hw)
 			rtl_lps_set_psmode(hw, EACTIVE);
 			rtl_lps_set_psmode(hw, EACTIVE);
 		}
 		}
 	}
 	}
-	spin_unlock(&rtlpriv->locks.lps_lock);
+	spin_unlock_irqrestore(&rtlpriv->locks.lps_lock, flags);
 }
 }
 
 
 /* For sw LPS*/
 /* For sw LPS*/
@@ -539,9 +540,9 @@ void rtl_swlps_rf_awake(struct ieee80211_hw *hw)
 		RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
 		RT_CLEAR_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM);
 	}
 	}
 
 
-	spin_lock(&rtlpriv->locks.lps_lock);
+	spin_lock_irq(&rtlpriv->locks.lps_lock);
 	rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS);
 	rtl_ps_set_rf_state(hw, ERFON, RF_CHANGE_BY_PS);
-	spin_unlock(&rtlpriv->locks.lps_lock);
+	spin_unlock_irq(&rtlpriv->locks.lps_lock);
 }
 }
 
 
 void rtl_swlps_rfon_wq_callback(void *data)
 void rtl_swlps_rfon_wq_callback(void *data)
@@ -574,9 +575,9 @@ void rtl_swlps_rf_sleep(struct ieee80211_hw *hw)
 	if (rtlpriv->link_info.busytraffic)
 	if (rtlpriv->link_info.busytraffic)
 		return;
 		return;
 
 
-	spin_lock(&rtlpriv->locks.lps_lock);
+	spin_lock_irq(&rtlpriv->locks.lps_lock);
 	rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS);
 	rtl_ps_set_rf_state(hw, ERFSLEEP, RF_CHANGE_BY_PS);
-	spin_unlock(&rtlpriv->locks.lps_lock);
+	spin_unlock_irq(&rtlpriv->locks.lps_lock);
 
 
 	if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
 	if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM &&
 		!RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {
 		!RT_IN_PS_LEVEL(ppsc, RT_PS_LEVEL_ASPM)) {

+ 1 - 1
drivers/net/xen-netback/netback.c

@@ -1021,7 +1021,7 @@ static int xen_netbk_tx_check_gop(struct xen_netbk *netbk,
 		pending_idx = *((u16 *)skb->data);
 		pending_idx = *((u16 *)skb->data);
 		xen_netbk_idx_release(netbk, pending_idx);
 		xen_netbk_idx_release(netbk, pending_idx);
 		for (j = start; j < i; j++) {
 		for (j = start; j < i; j++) {
-			pending_idx = frag_get_pending_idx(&shinfo->frags[i]);
+			pending_idx = frag_get_pending_idx(&shinfo->frags[j]);
 			xen_netbk_idx_release(netbk, pending_idx);
 			xen_netbk_idx_release(netbk, pending_idx);
 		}
 		}
 
 

+ 2 - 0
include/linux/netdevice.h

@@ -2536,6 +2536,8 @@ extern void		net_disable_timestamp(void);
 extern void *dev_seq_start(struct seq_file *seq, loff_t *pos);
 extern void *dev_seq_start(struct seq_file *seq, loff_t *pos);
 extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
 extern void *dev_seq_next(struct seq_file *seq, void *v, loff_t *pos);
 extern void dev_seq_stop(struct seq_file *seq, void *v);
 extern void dev_seq_stop(struct seq_file *seq, void *v);
+extern int dev_seq_open_ops(struct inode *inode, struct file *file,
+			    const struct seq_operations *ops);
 #endif
 #endif
 
 
 extern int netdev_class_create_file(struct class_attribute *class_attr);
 extern int netdev_class_create_file(struct class_attribute *class_attr);

+ 3 - 3
include/linux/pkt_sched.h

@@ -30,7 +30,7 @@
  */
  */
 
 
 struct tc_stats {
 struct tc_stats {
-	__u64	bytes;			/* NUmber of enqueues bytes */
+	__u64	bytes;			/* Number of enqueued bytes */
 	__u32	packets;		/* Number of enqueued packets	*/
 	__u32	packets;		/* Number of enqueued packets	*/
 	__u32	drops;			/* Packets dropped because of lack of resources */
 	__u32	drops;			/* Packets dropped because of lack of resources */
 	__u32	overlimits;		/* Number of throttle events when this
 	__u32	overlimits;		/* Number of throttle events when this
@@ -297,7 +297,7 @@ struct tc_htb_glob {
 	__u32 debug;		/* debug flags */
 	__u32 debug;		/* debug flags */
 
 
 	/* stats */
 	/* stats */
-	__u32 direct_pkts; /* count of non shapped packets */
+	__u32 direct_pkts; /* count of non shaped packets */
 };
 };
 enum {
 enum {
 	TCA_HTB_UNSPEC,
 	TCA_HTB_UNSPEC,
@@ -503,7 +503,7 @@ enum {
 };
 };
 #define NETEM_LOSS_MAX (__NETEM_LOSS_MAX - 1)
 #define NETEM_LOSS_MAX (__NETEM_LOSS_MAX - 1)
 
 
-/* State transition probablities for 4 state model */
+/* State transition probabilities for 4 state model */
 struct tc_netem_gimodel {
 struct tc_netem_gimodel {
 	__u32	p13;
 	__u32	p13;
 	__u32	p31;
 	__u32	p31;

+ 1 - 6
include/net/dst.h

@@ -205,12 +205,7 @@ dst_feature(const struct dst_entry *dst, u32 feature)
 
 
 static inline u32 dst_mtu(const struct dst_entry *dst)
 static inline u32 dst_mtu(const struct dst_entry *dst)
 {
 {
-	u32 mtu = dst_metric_raw(dst, RTAX_MTU);
-
-	if (!mtu)
-		mtu = dst->ops->default_mtu(dst);
-
-	return mtu;
+	return dst->ops->mtu(dst);
 }
 }
 
 
 /* RTT metrics are stored in milliseconds for user ABI, but used as jiffies */
 /* RTT metrics are stored in milliseconds for user ABI, but used as jiffies */

+ 1 - 1
include/net/dst_ops.h

@@ -17,7 +17,7 @@ struct dst_ops {
 	int			(*gc)(struct dst_ops *ops);
 	int			(*gc)(struct dst_ops *ops);
 	struct dst_entry *	(*check)(struct dst_entry *, __u32 cookie);
 	struct dst_entry *	(*check)(struct dst_entry *, __u32 cookie);
 	unsigned int		(*default_advmss)(const struct dst_entry *);
 	unsigned int		(*default_advmss)(const struct dst_entry *);
-	unsigned int		(*default_mtu)(const struct dst_entry *);
+	unsigned int		(*mtu)(const struct dst_entry *);
 	u32 *			(*cow_metrics)(struct dst_entry *, unsigned long);
 	u32 *			(*cow_metrics)(struct dst_entry *, unsigned long);
 	void			(*destroy)(struct dst_entry *);
 	void			(*destroy)(struct dst_entry *);
 	void			(*ifdown)(struct dst_entry *,
 	void			(*ifdown)(struct dst_entry *,

+ 2 - 0
include/net/inet_sock.h

@@ -31,6 +31,7 @@
 /** struct ip_options - IP Options
 /** struct ip_options - IP Options
  *
  *
  * @faddr - Saved first hop address
  * @faddr - Saved first hop address
+ * @nexthop - Saved nexthop address in LSRR and SSRR
  * @is_data - Options in __data, rather than skb
  * @is_data - Options in __data, rather than skb
  * @is_strictroute - Strict source route
  * @is_strictroute - Strict source route
  * @srr_is_hit - Packet destination addr was our one
  * @srr_is_hit - Packet destination addr was our one
@@ -41,6 +42,7 @@
  */
  */
 struct ip_options {
 struct ip_options {
 	__be32		faddr;
 	__be32		faddr;
+	__be32		nexthop;
 	unsigned char	optlen;
 	unsigned char	optlen;
 	unsigned char	srr;
 	unsigned char	srr;
 	unsigned char	rr;
 	unsigned char	rr;

+ 1 - 0
include/net/inetpeer.h

@@ -35,6 +35,7 @@ struct inet_peer {
 
 
 	u32			metrics[RTAX_MAX];
 	u32			metrics[RTAX_MAX];
 	u32			rate_tokens;	/* rate limiting for ICMP */
 	u32			rate_tokens;	/* rate limiting for ICMP */
+	int			redirect_genid;
 	unsigned long		rate_last;
 	unsigned long		rate_last;
 	unsigned long		pmtu_expires;
 	unsigned long		pmtu_expires;
 	u32			pmtu_orig;
 	u32			pmtu_orig;

+ 10 - 9
include/net/netfilter/nf_conntrack_ecache.h

@@ -67,18 +67,18 @@ struct nf_ct_event_notifier {
 	int (*fcn)(unsigned int events, struct nf_ct_event *item);
 	int (*fcn)(unsigned int events, struct nf_ct_event *item);
 };
 };
 
 
-extern struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
-extern int nf_conntrack_register_notifier(struct nf_ct_event_notifier *nb);
-extern void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *nb);
+extern int nf_conntrack_register_notifier(struct net *net, struct nf_ct_event_notifier *nb);
+extern void nf_conntrack_unregister_notifier(struct net *net, struct nf_ct_event_notifier *nb);
 
 
 extern void nf_ct_deliver_cached_events(struct nf_conn *ct);
 extern void nf_ct_deliver_cached_events(struct nf_conn *ct);
 
 
 static inline void
 static inline void
 nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
 nf_conntrack_event_cache(enum ip_conntrack_events event, struct nf_conn *ct)
 {
 {
+	struct net *net = nf_ct_net(ct);
 	struct nf_conntrack_ecache *e;
 	struct nf_conntrack_ecache *e;
 
 
-	if (nf_conntrack_event_cb == NULL)
+	if (net->ct.nf_conntrack_event_cb == NULL)
 		return;
 		return;
 
 
 	e = nf_ct_ecache_find(ct);
 	e = nf_ct_ecache_find(ct);
@@ -95,11 +95,12 @@ nf_conntrack_eventmask_report(unsigned int eventmask,
 			      int report)
 			      int report)
 {
 {
 	int ret = 0;
 	int ret = 0;
+	struct net *net = nf_ct_net(ct);
 	struct nf_ct_event_notifier *notify;
 	struct nf_ct_event_notifier *notify;
 	struct nf_conntrack_ecache *e;
 	struct nf_conntrack_ecache *e;
 
 
 	rcu_read_lock();
 	rcu_read_lock();
-	notify = rcu_dereference(nf_conntrack_event_cb);
+	notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
 	if (notify == NULL)
 	if (notify == NULL)
 		goto out_unlock;
 		goto out_unlock;
 
 
@@ -164,9 +165,8 @@ struct nf_exp_event_notifier {
 	int (*fcn)(unsigned int events, struct nf_exp_event *item);
 	int (*fcn)(unsigned int events, struct nf_exp_event *item);
 };
 };
 
 
-extern struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
-extern int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *nb);
-extern void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *nb);
+extern int nf_ct_expect_register_notifier(struct net *net, struct nf_exp_event_notifier *nb);
+extern void nf_ct_expect_unregister_notifier(struct net *net, struct nf_exp_event_notifier *nb);
 
 
 static inline void
 static inline void
 nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
 nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
@@ -174,11 +174,12 @@ nf_ct_expect_event_report(enum ip_conntrack_expect_events event,
 			  u32 pid,
 			  u32 pid,
 			  int report)
 			  int report)
 {
 {
+	struct net *net = nf_ct_exp_net(exp);
 	struct nf_exp_event_notifier *notify;
 	struct nf_exp_event_notifier *notify;
 	struct nf_conntrack_ecache *e;
 	struct nf_conntrack_ecache *e;
 
 
 	rcu_read_lock();
 	rcu_read_lock();
-	notify = rcu_dereference(nf_expect_event_cb);
+	notify = rcu_dereference(net->ct.nf_expect_event_cb);
 	if (notify == NULL)
 	if (notify == NULL)
 		goto out_unlock;
 		goto out_unlock;
 
 

+ 2 - 0
include/net/netns/conntrack.h

@@ -18,6 +18,8 @@ struct netns_ct {
 	struct hlist_nulls_head	unconfirmed;
 	struct hlist_nulls_head	unconfirmed;
 	struct hlist_nulls_head	dying;
 	struct hlist_nulls_head	dying;
 	struct ip_conntrack_stat __percpu *stat;
 	struct ip_conntrack_stat __percpu *stat;
+	struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb;
+	struct nf_exp_event_notifier __rcu *nf_expect_event_cb;
 	int			sysctl_events;
 	int			sysctl_events;
 	unsigned int		sysctl_events_retry_timeout;
 	unsigned int		sysctl_events_retry_timeout;
 	int			sysctl_acct;
 	int			sysctl_acct;

+ 6 - 9
include/net/red.h

@@ -116,7 +116,7 @@ struct red_parms {
 	u32		qR;		/* Cached random number */
 	u32		qR;		/* Cached random number */
 
 
 	unsigned long	qavg;		/* Average queue length: A scaled */
 	unsigned long	qavg;		/* Average queue length: A scaled */
-	psched_time_t	qidlestart;	/* Start of current idle period */
+	ktime_t		qidlestart;	/* Start of current idle period */
 };
 };
 
 
 static inline u32 red_rmask(u8 Plog)
 static inline u32 red_rmask(u8 Plog)
@@ -148,17 +148,17 @@ static inline void red_set_parms(struct red_parms *p,
 
 
 static inline int red_is_idling(struct red_parms *p)
 static inline int red_is_idling(struct red_parms *p)
 {
 {
-	return p->qidlestart != PSCHED_PASTPERFECT;
+	return p->qidlestart.tv64 != 0;
 }
 }
 
 
 static inline void red_start_of_idle_period(struct red_parms *p)
 static inline void red_start_of_idle_period(struct red_parms *p)
 {
 {
-	p->qidlestart = psched_get_time();
+	p->qidlestart = ktime_get();
 }
 }
 
 
 static inline void red_end_of_idle_period(struct red_parms *p)
 static inline void red_end_of_idle_period(struct red_parms *p)
 {
 {
-	p->qidlestart = PSCHED_PASTPERFECT;
+	p->qidlestart.tv64 = 0;
 }
 }
 
 
 static inline void red_restart(struct red_parms *p)
 static inline void red_restart(struct red_parms *p)
@@ -170,13 +170,10 @@ static inline void red_restart(struct red_parms *p)
 
 
 static inline unsigned long red_calc_qavg_from_idle_time(struct red_parms *p)
 static inline unsigned long red_calc_qavg_from_idle_time(struct red_parms *p)
 {
 {
-	psched_time_t now;
-	long us_idle;
+	s64 delta = ktime_us_delta(ktime_get(), p->qidlestart);
+	long us_idle = min_t(s64, delta, p->Scell_max);
 	int  shift;
 	int  shift;
 
 
-	now = psched_get_time();
-	us_idle = psched_tdiff_bounded(now, p->qidlestart, p->Scell_max);
-
 	/*
 	/*
 	 * The problem: ideally, average length queue recalcultion should
 	 * The problem: ideally, average length queue recalcultion should
 	 * be done over constant clock intervals. This is too expensive, so
 	 * be done over constant clock intervals. This is too expensive, so

+ 2 - 2
include/net/route.h

@@ -71,12 +71,12 @@ struct rtable {
 	struct fib_info		*fi; /* for client ref to shared metrics */
 	struct fib_info		*fi; /* for client ref to shared metrics */
 };
 };
 
 
-static inline bool rt_is_input_route(struct rtable *rt)
+static inline bool rt_is_input_route(const struct rtable *rt)
 {
 {
 	return rt->rt_route_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(const struct rtable *rt)
 {
 {
 	return rt->rt_route_iif == 0;
 	return rt->rt_route_iif == 0;
 }
 }

+ 6 - 0
net/bridge/br_netlink.c

@@ -18,6 +18,7 @@
 #include <net/sock.h>
 #include <net/sock.h>
 
 
 #include "br_private.h"
 #include "br_private.h"
+#include "br_private_stp.h"
 
 
 static inline size_t br_nlmsg_size(void)
 static inline size_t br_nlmsg_size(void)
 {
 {
@@ -188,6 +189,11 @@ static int br_rtm_setlink(struct sk_buff *skb,  struct nlmsghdr *nlh, void *arg)
 
 
 	p->state = new_state;
 	p->state = new_state;
 	br_log_state(p);
 	br_log_state(p);
+
+	spin_lock_bh(&p->br->lock);
+	br_port_state_selection(p->br);
+	spin_unlock_bh(&p->br->lock);
+
 	br_ifinfo_notify(RTM_NEWLINK, p);
 	br_ifinfo_notify(RTM_NEWLINK, p);
 
 
 	return 0;
 	return 0;

+ 14 - 15
net/bridge/br_stp.c

@@ -399,25 +399,24 @@ void br_port_state_selection(struct net_bridge *br)
 	struct net_bridge_port *p;
 	struct net_bridge_port *p;
 	unsigned int liveports = 0;
 	unsigned int liveports = 0;
 
 
-	/* Don't change port states if userspace is handling STP */
-	if (br->stp_enabled == BR_USER_STP)
-		return;
-
 	list_for_each_entry(p, &br->port_list, list) {
 	list_for_each_entry(p, &br->port_list, list) {
 		if (p->state == BR_STATE_DISABLED)
 		if (p->state == BR_STATE_DISABLED)
 			continue;
 			continue;
 
 
-		if (p->port_no == br->root_port) {
-			p->config_pending = 0;
-			p->topology_change_ack = 0;
-			br_make_forwarding(p);
-		} else if (br_is_designated_port(p)) {
-			del_timer(&p->message_age_timer);
-			br_make_forwarding(p);
-		} else {
-			p->config_pending = 0;
-			p->topology_change_ack = 0;
-			br_make_blocking(p);
+		/* Don't change port states if userspace is handling STP */
+		if (br->stp_enabled != BR_USER_STP) {
+			if (p->port_no == br->root_port) {
+				p->config_pending = 0;
+				p->topology_change_ack = 0;
+				br_make_forwarding(p);
+			} else if (br_is_designated_port(p)) {
+				del_timer(&p->message_age_timer);
+				br_make_forwarding(p);
+			} else {
+				p->config_pending = 0;
+				p->topology_change_ack = 0;
+				br_make_blocking(p);
+			}
 		}
 		}
 
 
 		if (p->state == BR_STATE_FORWARDING)
 		if (p->state == BR_STATE_FORWARDING)

+ 6 - 5
net/caif/cffrml.c

@@ -136,20 +136,21 @@ static int cffrml_receive(struct cflayer *layr, struct cfpkt *pkt)
 
 
 static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
 static int cffrml_transmit(struct cflayer *layr, struct cfpkt *pkt)
 {
 {
-	int tmp;
 	u16 chks;
 	u16 chks;
 	u16 len;
 	u16 len;
+	__le16 data;
+
 	struct cffrml *this = container_obj(layr);
 	struct cffrml *this = container_obj(layr);
 	if (this->dofcs) {
 	if (this->dofcs) {
 		chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
 		chks = cfpkt_iterate(pkt, cffrml_checksum, 0xffff);
-		tmp = cpu_to_le16(chks);
-		cfpkt_add_trail(pkt, &tmp, 2);
+		data = cpu_to_le16(chks);
+		cfpkt_add_trail(pkt, &data, 2);
 	} else {
 	} else {
 		cfpkt_pad_trail(pkt, 2);
 		cfpkt_pad_trail(pkt, 2);
 	}
 	}
 	len = cfpkt_getlen(pkt);
 	len = cfpkt_getlen(pkt);
-	tmp = cpu_to_le16(len);
-	cfpkt_add_head(pkt, &tmp, 2);
+	data = cpu_to_le16(len);
+	cfpkt_add_head(pkt, &data, 2);
 	cfpkt_info(pkt)->hdr_len += 2;
 	cfpkt_info(pkt)->hdr_len += 2;
 	if (cfpkt_erroneous(pkt)) {
 	if (cfpkt_erroneous(pkt)) {
 		pr_err("Packet is erroneous!\n");
 		pr_err("Packet is erroneous!\n");

+ 8 - 1
net/core/dev.c

@@ -1396,7 +1396,7 @@ rollback:
 	for_each_net(net) {
 	for_each_net(net) {
 		for_each_netdev(net, dev) {
 		for_each_netdev(net, dev) {
 			if (dev == last)
 			if (dev == last)
-				break;
+				goto outroll;
 
 
 			if (dev->flags & IFF_UP) {
 			if (dev->flags & IFF_UP) {
 				nb->notifier_call(nb, NETDEV_GOING_DOWN, dev);
 				nb->notifier_call(nb, NETDEV_GOING_DOWN, dev);
@@ -1407,6 +1407,7 @@ rollback:
 		}
 		}
 	}
 	}
 
 
+outroll:
 	raw_notifier_chain_unregister(&netdev_chain, nb);
 	raw_notifier_chain_unregister(&netdev_chain, nb);
 	goto unlock;
 	goto unlock;
 }
 }
@@ -4282,6 +4283,12 @@ static int dev_seq_open(struct inode *inode, struct file *file)
 			    sizeof(struct dev_iter_state));
 			    sizeof(struct dev_iter_state));
 }
 }
 
 
+int dev_seq_open_ops(struct inode *inode, struct file *file,
+		     const struct seq_operations *ops)
+{
+	return seq_open_net(inode, file, ops, sizeof(struct dev_iter_state));
+}
+
 static const struct file_operations dev_seq_fops = {
 static const struct file_operations dev_seq_fops = {
 	.owner	 = THIS_MODULE,
 	.owner	 = THIS_MODULE,
 	.open    = dev_seq_open,
 	.open    = dev_seq_open,

+ 1 - 2
net/core/dev_addr_lists.c

@@ -696,8 +696,7 @@ static const struct seq_operations dev_mc_seq_ops = {
 
 
 static int dev_mc_seq_open(struct inode *inode, struct file *file)
 static int dev_mc_seq_open(struct inode *inode, struct file *file)
 {
 {
-	return seq_open_net(inode, file, &dev_mc_seq_ops,
-			    sizeof(struct seq_net_private));
+	return dev_seq_open_ops(inode, file, &dev_mc_seq_ops);
 }
 }
 
 
 static const struct file_operations dev_mc_seq_fops = {
 static const struct file_operations dev_mc_seq_fops = {

+ 4 - 1
net/core/neighbour.c

@@ -2397,7 +2397,10 @@ static struct pneigh_entry *pneigh_get_next(struct seq_file *seq,
 	struct net *net = seq_file_net(seq);
 	struct net *net = seq_file_net(seq);
 	struct neigh_table *tbl = state->tbl;
 	struct neigh_table *tbl = state->tbl;
 
 
-	pn = pn->next;
+	do {
+		pn = pn->next;
+	} while (pn && !net_eq(pneigh_net(pn), net));
+
 	while (!pn) {
 	while (!pn) {
 		if (++state->bucket > PNEIGH_HASHMASK)
 		if (++state->bucket > PNEIGH_HASHMASK)
 			break;
 			break;

+ 1 - 1
net/core/skbuff.c

@@ -2230,7 +2230,7 @@ static int skb_prepare_for_shift(struct sk_buff *skb)
  * @shiftlen: shift up to this many bytes
  * @shiftlen: shift up to this many bytes
  *
  *
  * Attempts to shift up to shiftlen worth of bytes, which may be less than
  * Attempts to shift up to shiftlen worth of bytes, which may be less than
- * the length of the skb, from tgt to skb. Returns number bytes shifted.
+ * the length of the skb, from skb to tgt. Returns number bytes shifted.
  * It's up to caller to free skb if everything was shifted.
  * It's up to caller to free skb if everything was shifted.
  *
  *
  * If @tgt runs out of frags, the whole operation is aborted.
  * If @tgt runs out of frags, the whole operation is aborted.

+ 1 - 0
net/dccp/ipv4.c

@@ -111,6 +111,7 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
 	rt = ip_route_newports(fl4, rt, orig_sport, orig_dport,
 	rt = ip_route_newports(fl4, rt, orig_sport, orig_dport,
 			       inet->inet_sport, inet->inet_dport, sk);
 			       inet->inet_sport, inet->inet_dport, sk);
 	if (IS_ERR(rt)) {
 	if (IS_ERR(rt)) {
+		err = PTR_ERR(rt);
 		rt = NULL;
 		rt = NULL;
 		goto failure;
 		goto failure;
 	}
 	}

+ 6 - 4
net/decnet/dn_route.c

@@ -112,7 +112,7 @@ static unsigned long dn_rt_deadline;
 static int dn_dst_gc(struct dst_ops *ops);
 static int dn_dst_gc(struct dst_ops *ops);
 static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
 static struct dst_entry *dn_dst_check(struct dst_entry *, __u32);
 static unsigned int dn_dst_default_advmss(const struct dst_entry *dst);
 static unsigned int dn_dst_default_advmss(const struct dst_entry *dst);
-static unsigned int dn_dst_default_mtu(const struct dst_entry *dst);
+static unsigned int dn_dst_mtu(const struct dst_entry *dst);
 static void dn_dst_destroy(struct dst_entry *);
 static void dn_dst_destroy(struct dst_entry *);
 static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
 static struct dst_entry *dn_dst_negative_advice(struct dst_entry *);
 static void dn_dst_link_failure(struct sk_buff *);
 static void dn_dst_link_failure(struct sk_buff *);
@@ -135,7 +135,7 @@ static struct dst_ops dn_dst_ops = {
 	.gc =			dn_dst_gc,
 	.gc =			dn_dst_gc,
 	.check =		dn_dst_check,
 	.check =		dn_dst_check,
 	.default_advmss =	dn_dst_default_advmss,
 	.default_advmss =	dn_dst_default_advmss,
-	.default_mtu =		dn_dst_default_mtu,
+	.mtu =			dn_dst_mtu,
 	.cow_metrics =		dst_cow_metrics_generic,
 	.cow_metrics =		dst_cow_metrics_generic,
 	.destroy =		dn_dst_destroy,
 	.destroy =		dn_dst_destroy,
 	.negative_advice =	dn_dst_negative_advice,
 	.negative_advice =	dn_dst_negative_advice,
@@ -825,9 +825,11 @@ static unsigned int dn_dst_default_advmss(const struct dst_entry *dst)
 	return dn_mss_from_pmtu(dst->dev, dst_mtu(dst));
 	return dn_mss_from_pmtu(dst->dev, dst_mtu(dst));
 }
 }
 
 
-static unsigned int dn_dst_default_mtu(const struct dst_entry *dst)
+static unsigned int dn_dst_mtu(const struct dst_entry *dst)
 {
 {
-	return dst->dev->mtu;
+	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+	return mtu ? : dst->dev->mtu;
 }
 }
 
 
 static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)
 static struct neighbour *dn_dst_neigh_lookup(const struct dst_entry *dst, const void *daddr)

+ 5 - 12
net/decnet/dn_timer.c

@@ -36,16 +36,13 @@ static void dn_slow_timer(unsigned long arg);
 
 
 void dn_start_slow_timer(struct sock *sk)
 void dn_start_slow_timer(struct sock *sk)
 {
 {
-	sk->sk_timer.expires	= jiffies + SLOW_INTERVAL;
-	sk->sk_timer.function	= dn_slow_timer;
-	sk->sk_timer.data	= (unsigned long)sk;
-
-	add_timer(&sk->sk_timer);
+	setup_timer(&sk->sk_timer, dn_slow_timer, (unsigned long)sk);
+	sk_reset_timer(sk, &sk->sk_timer, jiffies + SLOW_INTERVAL);
 }
 }
 
 
 void dn_stop_slow_timer(struct sock *sk)
 void dn_stop_slow_timer(struct sock *sk)
 {
 {
-	del_timer(&sk->sk_timer);
+	sk_stop_timer(sk, &sk->sk_timer);
 }
 }
 
 
 static void dn_slow_timer(unsigned long arg)
 static void dn_slow_timer(unsigned long arg)
@@ -53,12 +50,10 @@ static void dn_slow_timer(unsigned long arg)
 	struct sock *sk = (struct sock *)arg;
 	struct sock *sk = (struct sock *)arg;
 	struct dn_scp *scp = DN_SK(sk);
 	struct dn_scp *scp = DN_SK(sk);
 
 
-	sock_hold(sk);
 	bh_lock_sock(sk);
 	bh_lock_sock(sk);
 
 
 	if (sock_owned_by_user(sk)) {
 	if (sock_owned_by_user(sk)) {
-		sk->sk_timer.expires = jiffies + HZ / 10;
-		add_timer(&sk->sk_timer);
+		sk_reset_timer(sk, &sk->sk_timer, jiffies + HZ / 10);
 		goto out;
 		goto out;
 	}
 	}
 
 
@@ -100,9 +95,7 @@ static void dn_slow_timer(unsigned long arg)
 			scp->keepalive_fxn(sk);
 			scp->keepalive_fxn(sk);
 	}
 	}
 
 
-	sk->sk_timer.expires = jiffies + SLOW_INTERVAL;
-
-	add_timer(&sk->sk_timer);
+	sk_reset_timer(sk, &sk->sk_timer, jiffies + SLOW_INTERVAL);
 out:
 out:
 	bh_unlock_sock(sk);
 	bh_unlock_sock(sk);
 	sock_put(sk);
 	sock_put(sk);

+ 5 - 0
net/ipv4/devinet.c

@@ -1490,7 +1490,9 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
 			     void __user *buffer,
 			     void __user *buffer,
 			     size_t *lenp, loff_t *ppos)
 			     size_t *lenp, loff_t *ppos)
 {
 {
+	int old_value = *(int *)ctl->data;
 	int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
 	int ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
+	int new_value = *(int *)ctl->data;
 
 
 	if (write) {
 	if (write) {
 		struct ipv4_devconf *cnf = ctl->extra1;
 		struct ipv4_devconf *cnf = ctl->extra1;
@@ -1501,6 +1503,9 @@ static int devinet_conf_proc(ctl_table *ctl, int write,
 
 
 		if (cnf == net->ipv4.devconf_dflt)
 		if (cnf == net->ipv4.devconf_dflt)
 			devinet_copy_dflt_conf(net, i);
 			devinet_copy_dflt_conf(net, i);
+		if (i == IPV4_DEVCONF_ACCEPT_LOCAL - 1)
+			if ((new_value == 0) && (old_value != 0))
+				rt_cache_flush(net, 0);
 	}
 	}
 
 
 	return ret;
 	return ret;

+ 2 - 1
net/ipv4/igmp.c

@@ -1716,7 +1716,8 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
 	if (err) {
 	if (err) {
 		int j;
 		int j;
 
 
-		pmc->sfcount[sfmode]--;
+		if (!delta)
+			pmc->sfcount[sfmode]--;
 		for (j=0; j<i; j++)
 		for (j=0; j<i; j++)
 			(void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]);
 			(void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]);
 	} else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) {
 	} else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) {

+ 9 - 5
net/ipv4/inet_diag.c

@@ -108,9 +108,6 @@ static int inet_csk_diag_fill(struct sock *sk,
 		       icsk->icsk_ca_ops->name);
 		       icsk->icsk_ca_ops->name);
 	}
 	}
 
 
-	if ((ext & (1 << (INET_DIAG_TOS - 1))) && (sk->sk_family != AF_INET6))
-		RTA_PUT_U8(skb, INET_DIAG_TOS, inet->tos);
-
 	r->idiag_family = sk->sk_family;
 	r->idiag_family = sk->sk_family;
 	r->idiag_state = sk->sk_state;
 	r->idiag_state = sk->sk_state;
 	r->idiag_timer = 0;
 	r->idiag_timer = 0;
@@ -125,16 +122,23 @@ static int inet_csk_diag_fill(struct sock *sk,
 	r->id.idiag_src[0] = inet->inet_rcv_saddr;
 	r->id.idiag_src[0] = inet->inet_rcv_saddr;
 	r->id.idiag_dst[0] = inet->inet_daddr;
 	r->id.idiag_dst[0] = inet->inet_daddr;
 
 
+	/* IPv6 dual-stack sockets use inet->tos for IPv4 connections,
+	 * hence this needs to be included regardless of socket family.
+	 */
+	if (ext & (1 << (INET_DIAG_TOS - 1)))
+		RTA_PUT_U8(skb, INET_DIAG_TOS, inet->tos);
+
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 #if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
 	if (r->idiag_family == AF_INET6) {
 	if (r->idiag_family == AF_INET6) {
 		const struct ipv6_pinfo *np = inet6_sk(sk);
 		const struct ipv6_pinfo *np = inet6_sk(sk);
 
 
+		if (ext & (1 << (INET_DIAG_TCLASS - 1)))
+			RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass);
+
 		ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
 		ipv6_addr_copy((struct in6_addr *)r->id.idiag_src,
 			       &np->rcv_saddr);
 			       &np->rcv_saddr);
 		ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
 		ipv6_addr_copy((struct in6_addr *)r->id.idiag_dst,
 			       &np->daddr);
 			       &np->daddr);
-		if (ext & (1 << (INET_DIAG_TCLASS - 1)))
-			RTA_PUT_U8(skb, INET_DIAG_TCLASS, np->tclass);
 	}
 	}
 #endif
 #endif
 
 

+ 1 - 1
net/ipv4/ip_forward.c

@@ -84,7 +84,7 @@ int ip_forward(struct sk_buff *skb)
 
 
 	rt = skb_rtable(skb);
 	rt = skb_rtable(skb);
 
 
-	if (opt->is_strictroute && ip_hdr(skb)->daddr != rt->rt_gateway)
+	if (opt->is_strictroute && opt->nexthop != rt->rt_gateway)
 		goto sr_failed;
 		goto sr_failed;
 
 
 	if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&
 	if (unlikely(skb->len > dst_mtu(&rt->dst) && !skb_is_gso(skb) &&

+ 3 - 2
net/ipv4/ip_options.c

@@ -568,12 +568,13 @@ void ip_forward_options(struct sk_buff *skb)
 		     ) {
 		     ) {
 			if (srrptr + 3 > srrspace)
 			if (srrptr + 3 > srrspace)
 				break;
 				break;
-			if (memcmp(&ip_hdr(skb)->daddr, &optptr[srrptr-1], 4) == 0)
+			if (memcmp(&opt->nexthop, &optptr[srrptr-1], 4) == 0)
 				break;
 				break;
 		}
 		}
 		if (srrptr + 3 <= srrspace) {
 		if (srrptr + 3 <= srrspace) {
 			opt->is_changed = 1;
 			opt->is_changed = 1;
 			ip_rt_get_source(&optptr[srrptr-1], skb, rt);
 			ip_rt_get_source(&optptr[srrptr-1], skb, rt);
+			ip_hdr(skb)->daddr = opt->nexthop;
 			optptr[2] = srrptr+4;
 			optptr[2] = srrptr+4;
 		} else if (net_ratelimit())
 		} else if (net_ratelimit())
 			printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
 			printk(KERN_CRIT "ip_forward(): Argh! Destination lost!\n");
@@ -640,7 +641,7 @@ int ip_options_rcv_srr(struct sk_buff *skb)
 	}
 	}
 	if (srrptr <= srrspace) {
 	if (srrptr <= srrspace) {
 		opt->srr_is_hit = 1;
 		opt->srr_is_hit = 1;
-		iph->daddr = nexthop;
+		opt->nexthop = nexthop;
 		opt->is_changed = 1;
 		opt->is_changed = 1;
 	}
 	}
 	return 0;
 	return 0;

+ 2 - 1
net/ipv4/netfilter.c

@@ -64,7 +64,8 @@ int ip_route_me_harder(struct sk_buff *skb, unsigned addr_type)
 	/* Change in oif may mean change in hh_len. */
 	/* Change in oif may mean change in hh_len. */
 	hh_len = skb_dst(skb)->dev->hard_header_len;
 	hh_len = skb_dst(skb)->dev->hard_header_len;
 	if (skb_headroom(skb) < hh_len &&
 	if (skb_headroom(skb) < hh_len &&
-	    pskb_expand_head(skb, hh_len - skb_headroom(skb), 0, GFP_ATOMIC))
+	    pskb_expand_head(skb, HH_DATA_ALIGN(hh_len - skb_headroom(skb)),
+				0, GFP_ATOMIC))
 		return -1;
 		return -1;
 
 
 	return 0;
 	return 0;

+ 0 - 1
net/ipv4/netfilter/Kconfig

@@ -325,7 +325,6 @@ config IP_NF_TARGET_TTL
 # raw + specific targets
 # raw + specific targets
 config IP_NF_RAW
 config IP_NF_RAW
 	tristate  'raw table support (required for NOTRACK/TRACE)'
 	tristate  'raw table support (required for NOTRACK/TRACE)'
-	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `raw' table to iptables. This table is the very
 	  This option adds a `raw' table to iptables. This table is the very
 	  first in the netfilter framework and hooks in at the PREROUTING
 	  first in the netfilter framework and hooks in at the PREROUTING

+ 49 - 18
net/ipv4/route.c

@@ -131,6 +131,7 @@ static int ip_rt_mtu_expires __read_mostly	= 10 * 60 * HZ;
 static int ip_rt_min_pmtu __read_mostly		= 512 + 20 + 20;
 static int ip_rt_min_pmtu __read_mostly		= 512 + 20 + 20;
 static int ip_rt_min_advmss __read_mostly	= 256;
 static int ip_rt_min_advmss __read_mostly	= 256;
 static int rt_chain_length_max __read_mostly	= 20;
 static int rt_chain_length_max __read_mostly	= 20;
+static int redirect_genid;
 
 
 /*
 /*
  *	Interface to generic destination cache.
  *	Interface to generic destination cache.
@@ -138,7 +139,7 @@ static int rt_chain_length_max __read_mostly	= 20;
 
 
 static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
 static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
 static unsigned int	 ipv4_default_advmss(const struct dst_entry *dst);
 static unsigned int	 ipv4_default_advmss(const struct dst_entry *dst);
-static unsigned int	 ipv4_default_mtu(const struct dst_entry *dst);
+static unsigned int	 ipv4_mtu(const struct dst_entry *dst);
 static void		 ipv4_dst_destroy(struct dst_entry *dst);
 static void		 ipv4_dst_destroy(struct dst_entry *dst);
 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
 static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
 static void		 ipv4_link_failure(struct sk_buff *skb);
 static void		 ipv4_link_failure(struct sk_buff *skb);
@@ -193,7 +194,7 @@ static struct dst_ops ipv4_dst_ops = {
 	.gc =			rt_garbage_collect,
 	.gc =			rt_garbage_collect,
 	.check =		ipv4_dst_check,
 	.check =		ipv4_dst_check,
 	.default_advmss =	ipv4_default_advmss,
 	.default_advmss =	ipv4_default_advmss,
-	.default_mtu =		ipv4_default_mtu,
+	.mtu =			ipv4_mtu,
 	.cow_metrics =		ipv4_cow_metrics,
 	.cow_metrics =		ipv4_cow_metrics,
 	.destroy =		ipv4_dst_destroy,
 	.destroy =		ipv4_dst_destroy,
 	.ifdown =		ipv4_dst_ifdown,
 	.ifdown =		ipv4_dst_ifdown,
@@ -416,9 +417,13 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
 	else {
 	else {
 		struct rtable *r = v;
 		struct rtable *r = v;
 		struct neighbour *n;
 		struct neighbour *n;
-		int len;
+		int len, HHUptod;
 
 
+		rcu_read_lock();
 		n = dst_get_neighbour(&r->dst);
 		n = dst_get_neighbour(&r->dst);
+		HHUptod = (n && (n->nud_state & NUD_CONNECTED)) ? 1 : 0;
+		rcu_read_unlock();
+
 		seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t"
 		seq_printf(seq, "%s\t%08X\t%08X\t%8X\t%d\t%u\t%d\t"
 			      "%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n",
 			      "%08X\t%d\t%u\t%u\t%02X\t%d\t%1d\t%08X%n",
 			r->dst.dev ? r->dst.dev->name : "*",
 			r->dst.dev ? r->dst.dev->name : "*",
@@ -432,7 +437,7 @@ static int rt_cache_seq_show(struct seq_file *seq, void *v)
 			      dst_metric(&r->dst, RTAX_RTTVAR)),
 			      dst_metric(&r->dst, RTAX_RTTVAR)),
 			r->rt_key_tos,
 			r->rt_key_tos,
 			-1,
 			-1,
-			(n && (n->nud_state & NUD_CONNECTED)) ? 1 : 0,
+			HHUptod,
 			r->rt_spec_dst, &len);
 			r->rt_spec_dst, &len);
 
 
 		seq_printf(seq, "%*s\n", 127 - len, "");
 		seq_printf(seq, "%*s\n", 127 - len, "");
@@ -837,6 +842,7 @@ static void rt_cache_invalidate(struct net *net)
 
 
 	get_random_bytes(&shuffle, sizeof(shuffle));
 	get_random_bytes(&shuffle, sizeof(shuffle));
 	atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
 	atomic_add(shuffle + 1U, &net->ipv4.rt_genid);
+	redirect_genid++;
 }
 }
 
 
 /*
 /*
@@ -1391,8 +1397,10 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
 
 
 				peer = rt->peer;
 				peer = rt->peer;
 				if (peer) {
 				if (peer) {
-					if (peer->redirect_learned.a4 != new_gw) {
+					if (peer->redirect_learned.a4 != new_gw ||
+					    peer->redirect_genid != redirect_genid) {
 						peer->redirect_learned.a4 = new_gw;
 						peer->redirect_learned.a4 = new_gw;
+						peer->redirect_genid = redirect_genid;
 						atomic_inc(&__rt_peer_genid);
 						atomic_inc(&__rt_peer_genid);
 					}
 					}
 					check_peer_redir(&rt->dst, peer);
 					check_peer_redir(&rt->dst, peer);
@@ -1685,12 +1693,8 @@ static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
 }
 }
 
 
 
 
-static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
+static struct rtable *ipv4_validate_peer(struct rtable *rt)
 {
 {
-	struct rtable *rt = (struct rtable *) dst;
-
-	if (rt_is_expired(rt))
-		return NULL;
 	if (rt->rt_peer_genid != rt_peer_genid()) {
 	if (rt->rt_peer_genid != rt_peer_genid()) {
 		struct inet_peer *peer;
 		struct inet_peer *peer;
 
 
@@ -1699,17 +1703,29 @@ static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
 
 
 		peer = rt->peer;
 		peer = rt->peer;
 		if (peer) {
 		if (peer) {
-			check_peer_pmtu(dst, peer);
+			check_peer_pmtu(&rt->dst, peer);
 
 
+			if (peer->redirect_genid != redirect_genid)
+				peer->redirect_learned.a4 = 0;
 			if (peer->redirect_learned.a4 &&
 			if (peer->redirect_learned.a4 &&
 			    peer->redirect_learned.a4 != rt->rt_gateway) {
 			    peer->redirect_learned.a4 != rt->rt_gateway) {
-				if (check_peer_redir(dst, peer))
+				if (check_peer_redir(&rt->dst, peer))
 					return NULL;
 					return NULL;
 			}
 			}
 		}
 		}
 
 
 		rt->rt_peer_genid = rt_peer_genid();
 		rt->rt_peer_genid = rt_peer_genid();
 	}
 	}
+	return rt;
+}
+
+static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie)
+{
+	struct rtable *rt = (struct rtable *) dst;
+
+	if (rt_is_expired(rt))
+		return NULL;
+	dst = (struct dst_entry *) ipv4_validate_peer(rt);
 	return dst;
 	return dst;
 }
 }
 
 
@@ -1814,12 +1830,17 @@ static unsigned int ipv4_default_advmss(const struct dst_entry *dst)
 	return advmss;
 	return advmss;
 }
 }
 
 
-static unsigned int ipv4_default_mtu(const struct dst_entry *dst)
+static unsigned int ipv4_mtu(const struct dst_entry *dst)
 {
 {
-	unsigned int mtu = dst->dev->mtu;
+	const struct rtable *rt = (const struct rtable *) dst;
+	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+	if (mtu && rt_is_output_route(rt))
+		return mtu;
+
+	mtu = dst->dev->mtu;
 
 
 	if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
 	if (unlikely(dst_metric_locked(dst, RTAX_MTU))) {
-		const struct rtable *rt = (const struct rtable *) dst;
 
 
 		if (rt->rt_gateway != rt->rt_dst && mtu > 576)
 		if (rt->rt_gateway != rt->rt_dst && mtu > 576)
 			mtu = 576;
 			mtu = 576;
@@ -1852,6 +1873,8 @@ static void rt_init_metrics(struct rtable *rt, const struct flowi4 *fl4,
 		dst_init_metrics(&rt->dst, peer->metrics, false);
 		dst_init_metrics(&rt->dst, peer->metrics, false);
 
 
 		check_peer_pmtu(&rt->dst, peer);
 		check_peer_pmtu(&rt->dst, peer);
+		if (peer->redirect_genid != redirect_genid)
+			peer->redirect_learned.a4 = 0;
 		if (peer->redirect_learned.a4 &&
 		if (peer->redirect_learned.a4 &&
 		    peer->redirect_learned.a4 != rt->rt_gateway) {
 		    peer->redirect_learned.a4 != rt->rt_gateway) {
 			rt->rt_gateway = peer->redirect_learned.a4;
 			rt->rt_gateway = peer->redirect_learned.a4;
@@ -2357,6 +2380,9 @@ int ip_route_input_common(struct sk_buff *skb, __be32 daddr, __be32 saddr,
 		    rth->rt_mark == skb->mark &&
 		    rth->rt_mark == skb->mark &&
 		    net_eq(dev_net(rth->dst.dev), net) &&
 		    net_eq(dev_net(rth->dst.dev), net) &&
 		    !rt_is_expired(rth)) {
 		    !rt_is_expired(rth)) {
+			rth = ipv4_validate_peer(rth);
+			if (!rth)
+				continue;
 			if (noref) {
 			if (noref) {
 				dst_use_noref(&rth->dst, jiffies);
 				dst_use_noref(&rth->dst, jiffies);
 				skb_dst_set_noref(skb, &rth->dst);
 				skb_dst_set_noref(skb, &rth->dst);
@@ -2732,6 +2758,9 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *flp4)
 			    (IPTOS_RT_MASK | RTO_ONLINK)) &&
 			    (IPTOS_RT_MASK | RTO_ONLINK)) &&
 		    net_eq(dev_net(rth->dst.dev), net) &&
 		    net_eq(dev_net(rth->dst.dev), net) &&
 		    !rt_is_expired(rth)) {
 		    !rt_is_expired(rth)) {
+			rth = ipv4_validate_peer(rth);
+			if (!rth)
+				continue;
 			dst_use(&rth->dst, jiffies);
 			dst_use(&rth->dst, jiffies);
 			RT_CACHE_STAT_INC(out_hit);
 			RT_CACHE_STAT_INC(out_hit);
 			rcu_read_unlock_bh();
 			rcu_read_unlock_bh();
@@ -2755,9 +2784,11 @@ static struct dst_entry *ipv4_blackhole_dst_check(struct dst_entry *dst, u32 coo
 	return NULL;
 	return NULL;
 }
 }
 
 
-static unsigned int ipv4_blackhole_default_mtu(const struct dst_entry *dst)
+static unsigned int ipv4_blackhole_mtu(const struct dst_entry *dst)
 {
 {
-	return 0;
+	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+	return mtu ? : dst->dev->mtu;
 }
 }
 
 
 static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
 static void ipv4_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -2775,7 +2806,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
 	.protocol		=	cpu_to_be16(ETH_P_IP),
 	.protocol		=	cpu_to_be16(ETH_P_IP),
 	.destroy		=	ipv4_dst_destroy,
 	.destroy		=	ipv4_dst_destroy,
 	.check			=	ipv4_blackhole_dst_check,
 	.check			=	ipv4_blackhole_dst_check,
-	.default_mtu		=	ipv4_blackhole_default_mtu,
+	.mtu			=	ipv4_blackhole_mtu,
 	.default_advmss		=	ipv4_default_advmss,
 	.default_advmss		=	ipv4_default_advmss,
 	.update_pmtu		=	ipv4_rt_blackhole_update_pmtu,
 	.update_pmtu		=	ipv4_rt_blackhole_update_pmtu,
 	.cow_metrics		=	ipv4_rt_blackhole_cow_metrics,
 	.cow_metrics		=	ipv4_rt_blackhole_cow_metrics,

+ 8 - 7
net/ipv4/udp.c

@@ -1164,7 +1164,7 @@ int udp_recvmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
 	struct inet_sock *inet = inet_sk(sk);
 	struct inet_sock *inet = inet_sk(sk);
 	struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
 	struct sockaddr_in *sin = (struct sockaddr_in *)msg->msg_name;
 	struct sk_buff *skb;
 	struct sk_buff *skb;
-	unsigned int ulen;
+	unsigned int ulen, copied;
 	int peeked;
 	int peeked;
 	int err;
 	int err;
 	int is_udplite = IS_UDPLITE(sk);
 	int is_udplite = IS_UDPLITE(sk);
@@ -1186,9 +1186,10 @@ try_again:
 		goto out;
 		goto out;
 
 
 	ulen = skb->len - sizeof(struct udphdr);
 	ulen = skb->len - sizeof(struct udphdr);
-	if (len > ulen)
-		len = ulen;
-	else if (len < ulen)
+	copied = len;
+	if (copied > ulen)
+		copied = ulen;
+	else if (copied < ulen)
 		msg->msg_flags |= MSG_TRUNC;
 		msg->msg_flags |= MSG_TRUNC;
 
 
 	/*
 	/*
@@ -1197,14 +1198,14 @@ try_again:
 	 * coverage checksum (UDP-Lite), do it before the copy.
 	 * coverage checksum (UDP-Lite), do it before the copy.
 	 */
 	 */
 
 
-	if (len < ulen || UDP_SKB_CB(skb)->partial_cov) {
+	if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
 		if (udp_lib_checksum_complete(skb))
 		if (udp_lib_checksum_complete(skb))
 			goto csum_copy_err;
 			goto csum_copy_err;
 	}
 	}
 
 
 	if (skb_csum_unnecessary(skb))
 	if (skb_csum_unnecessary(skb))
 		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
 		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
-					      msg->msg_iov, len);
+					      msg->msg_iov, copied);
 	else {
 	else {
 		err = skb_copy_and_csum_datagram_iovec(skb,
 		err = skb_copy_and_csum_datagram_iovec(skb,
 						       sizeof(struct udphdr),
 						       sizeof(struct udphdr),
@@ -1233,7 +1234,7 @@ try_again:
 	if (inet->cmsg_flags)
 	if (inet->cmsg_flags)
 		ip_cmsg_recv(msg, skb);
 		ip_cmsg_recv(msg, skb);
 
 
-	err = len;
+	err = copied;
 	if (flags & MSG_TRUNC)
 	if (flags & MSG_TRUNC)
 		err = ulen;
 		err = ulen;
 
 

+ 1 - 1
net/ipv6/inet6_connection_sock.c

@@ -85,7 +85,7 @@ struct dst_entry *inet6_csk_route_req(struct sock *sk,
  * request_sock (formerly open request) hash tables.
  * request_sock (formerly open request) hash tables.
  */
  */
 static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
 static u32 inet6_synq_hash(const struct in6_addr *raddr, const __be16 rport,
-			   const u32 rnd, const u16 synq_hsize)
+			   const u32 rnd, const u32 synq_hsize)
 {
 {
 	u32 c;
 	u32 c;
 
 

+ 1 - 1
net/ipv6/ipv6_sockglue.c

@@ -503,7 +503,7 @@ done:
 			goto e_inval;
 			goto e_inval;
 		if (val > 255 || val < -1)
 		if (val > 255 || val < -1)
 			goto e_inval;
 			goto e_inval;
-		np->mcast_hops = val;
+		np->mcast_hops = (val == -1 ? IPV6_DEFAULT_MCASTHOPS : val);
 		retv = 0;
 		retv = 0;
 		break;
 		break;
 
 

+ 1 - 1
net/ipv6/ndisc.c

@@ -1571,7 +1571,7 @@ void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
 	}
 	}
 	if (!rt->rt6i_peer)
 	if (!rt->rt6i_peer)
 		rt6_bind_peer(rt, 1);
 		rt6_bind_peer(rt, 1);
-	if (inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
+	if (!inet_peer_xrlim_allow(rt->rt6i_peer, 1*HZ))
 		goto release;
 		goto release;
 
 
 	if (dev->addr_len) {
 	if (dev->addr_len) {

+ 0 - 1
net/ipv6/netfilter/Kconfig

@@ -186,7 +186,6 @@ config IP6_NF_MANGLE
 
 
 config IP6_NF_RAW
 config IP6_NF_RAW
 	tristate  'raw table support (required for TRACE)'
 	tristate  'raw table support (required for TRACE)'
-	depends on NETFILTER_ADVANCED
 	help
 	help
 	  This option adds a `raw' table to ip6tables. This table is the very
 	  This option adds a `raw' table to ip6tables. This table is the very
 	  first in the netfilter framework and hooks in at the PREROUTING
 	  first in the netfilter framework and hooks in at the PREROUTING

+ 14 - 7
net/ipv6/route.c

@@ -77,7 +77,7 @@ static struct rt6_info *ip6_rt_copy(const struct rt6_info *ort,
 				    const struct in6_addr *dest);
 				    const struct in6_addr *dest);
 static struct dst_entry	*ip6_dst_check(struct dst_entry *dst, u32 cookie);
 static struct dst_entry	*ip6_dst_check(struct dst_entry *dst, u32 cookie);
 static unsigned int	 ip6_default_advmss(const struct dst_entry *dst);
 static unsigned int	 ip6_default_advmss(const struct dst_entry *dst);
-static unsigned int	 ip6_default_mtu(const struct dst_entry *dst);
+static unsigned int	 ip6_mtu(const struct dst_entry *dst);
 static struct dst_entry *ip6_negative_advice(struct dst_entry *);
 static struct dst_entry *ip6_negative_advice(struct dst_entry *);
 static void		ip6_dst_destroy(struct dst_entry *);
 static void		ip6_dst_destroy(struct dst_entry *);
 static void		ip6_dst_ifdown(struct dst_entry *,
 static void		ip6_dst_ifdown(struct dst_entry *,
@@ -144,7 +144,7 @@ static struct dst_ops ip6_dst_ops_template = {
 	.gc_thresh		=	1024,
 	.gc_thresh		=	1024,
 	.check			=	ip6_dst_check,
 	.check			=	ip6_dst_check,
 	.default_advmss		=	ip6_default_advmss,
 	.default_advmss		=	ip6_default_advmss,
-	.default_mtu		=	ip6_default_mtu,
+	.mtu			=	ip6_mtu,
 	.cow_metrics		=	ipv6_cow_metrics,
 	.cow_metrics		=	ipv6_cow_metrics,
 	.destroy		=	ip6_dst_destroy,
 	.destroy		=	ip6_dst_destroy,
 	.ifdown			=	ip6_dst_ifdown,
 	.ifdown			=	ip6_dst_ifdown,
@@ -155,9 +155,11 @@ static struct dst_ops ip6_dst_ops_template = {
 	.neigh_lookup		=	ip6_neigh_lookup,
 	.neigh_lookup		=	ip6_neigh_lookup,
 };
 };
 
 
-static unsigned int ip6_blackhole_default_mtu(const struct dst_entry *dst)
+static unsigned int ip6_blackhole_mtu(const struct dst_entry *dst)
 {
 {
-	return 0;
+	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+	return mtu ? : dst->dev->mtu;
 }
 }
 
 
 static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
 static void ip6_rt_blackhole_update_pmtu(struct dst_entry *dst, u32 mtu)
@@ -175,7 +177,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
 	.protocol		=	cpu_to_be16(ETH_P_IPV6),
 	.protocol		=	cpu_to_be16(ETH_P_IPV6),
 	.destroy		=	ip6_dst_destroy,
 	.destroy		=	ip6_dst_destroy,
 	.check			=	ip6_dst_check,
 	.check			=	ip6_dst_check,
-	.default_mtu		=	ip6_blackhole_default_mtu,
+	.mtu			=	ip6_blackhole_mtu,
 	.default_advmss		=	ip6_default_advmss,
 	.default_advmss		=	ip6_default_advmss,
 	.update_pmtu		=	ip6_rt_blackhole_update_pmtu,
 	.update_pmtu		=	ip6_rt_blackhole_update_pmtu,
 	.cow_metrics		=	ip6_rt_blackhole_cow_metrics,
 	.cow_metrics		=	ip6_rt_blackhole_cow_metrics,
@@ -1041,10 +1043,15 @@ static unsigned int ip6_default_advmss(const struct dst_entry *dst)
 	return mtu;
 	return mtu;
 }
 }
 
 
-static unsigned int ip6_default_mtu(const struct dst_entry *dst)
+static unsigned int ip6_mtu(const struct dst_entry *dst)
 {
 {
-	unsigned int mtu = IPV6_MIN_MTU;
 	struct inet6_dev *idev;
 	struct inet6_dev *idev;
+	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+	if (mtu)
+		return mtu;
+
+	mtu = IPV6_MIN_MTU;
 
 
 	rcu_read_lock();
 	rcu_read_lock();
 	idev = __in6_dev_get(dst->dev);
 	idev = __in6_dev_get(dst->dev);

+ 7 - 6
net/ipv6/tcp_ipv6.c

@@ -1255,6 +1255,13 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 	if (!want_cookie || tmp_opt.tstamp_ok)
 	if (!want_cookie || tmp_opt.tstamp_ok)
 		TCP_ECN_create_request(req, tcp_hdr(skb));
 		TCP_ECN_create_request(req, tcp_hdr(skb));
 
 
+	treq->iif = sk->sk_bound_dev_if;
+
+	/* So that link locals have meaning */
+	if (!sk->sk_bound_dev_if &&
+	    ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)
+		treq->iif = inet6_iif(skb);
+
 	if (!isn) {
 	if (!isn) {
 		struct inet_peer *peer = NULL;
 		struct inet_peer *peer = NULL;
 
 
@@ -1264,12 +1271,6 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
 			atomic_inc(&skb->users);
 			atomic_inc(&skb->users);
 			treq->pktopts = skb;
 			treq->pktopts = skb;
 		}
 		}
-		treq->iif = sk->sk_bound_dev_if;
-
-		/* So that link locals have meaning */
-		if (!sk->sk_bound_dev_if &&
-		    ipv6_addr_type(&treq->rmt_addr) & IPV6_ADDR_LINKLOCAL)
-			treq->iif = inet6_iif(skb);
 
 
 		if (want_cookie) {
 		if (want_cookie) {
 			isn = cookie_v6_init_sequence(sk, skb, &req->mss);
 			isn = cookie_v6_init_sequence(sk, skb, &req->mss);

+ 8 - 7
net/ipv6/udp.c

@@ -340,7 +340,7 @@ int udpv6_recvmsg(struct kiocb *iocb, struct sock *sk,
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct ipv6_pinfo *np = inet6_sk(sk);
 	struct inet_sock *inet = inet_sk(sk);
 	struct inet_sock *inet = inet_sk(sk);
 	struct sk_buff *skb;
 	struct sk_buff *skb;
-	unsigned int ulen;
+	unsigned int ulen, copied;
 	int peeked;
 	int peeked;
 	int err;
 	int err;
 	int is_udplite = IS_UDPLITE(sk);
 	int is_udplite = IS_UDPLITE(sk);
@@ -363,9 +363,10 @@ try_again:
 		goto out;
 		goto out;
 
 
 	ulen = skb->len - sizeof(struct udphdr);
 	ulen = skb->len - sizeof(struct udphdr);
-	if (len > ulen)
-		len = ulen;
-	else if (len < ulen)
+	copied = len;
+	if (copied > ulen)
+		copied = ulen;
+	else if (copied < ulen)
 		msg->msg_flags |= MSG_TRUNC;
 		msg->msg_flags |= MSG_TRUNC;
 
 
 	is_udp4 = (skb->protocol == htons(ETH_P_IP));
 	is_udp4 = (skb->protocol == htons(ETH_P_IP));
@@ -376,14 +377,14 @@ try_again:
 	 * coverage checksum (UDP-Lite), do it before the copy.
 	 * coverage checksum (UDP-Lite), do it before the copy.
 	 */
 	 */
 
 
-	if (len < ulen || UDP_SKB_CB(skb)->partial_cov) {
+	if (copied < ulen || UDP_SKB_CB(skb)->partial_cov) {
 		if (udp_lib_checksum_complete(skb))
 		if (udp_lib_checksum_complete(skb))
 			goto csum_copy_err;
 			goto csum_copy_err;
 	}
 	}
 
 
 	if (skb_csum_unnecessary(skb))
 	if (skb_csum_unnecessary(skb))
 		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
 		err = skb_copy_datagram_iovec(skb, sizeof(struct udphdr),
-					      msg->msg_iov,len);
+					      msg->msg_iov, copied       );
 	else {
 	else {
 		err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
 		err = skb_copy_and_csum_datagram_iovec(skb, sizeof(struct udphdr), msg->msg_iov);
 		if (err == -EINVAL)
 		if (err == -EINVAL)
@@ -432,7 +433,7 @@ try_again:
 			datagram_recv_ctl(sk, msg, skb);
 			datagram_recv_ctl(sk, msg, skb);
 	}
 	}
 
 
-	err = len;
+	err = copied;
 	if (flags & MSG_TRUNC)
 	if (flags & MSG_TRUNC)
 		err = ulen;
 		err = ulen;
 
 

+ 1 - 1
net/l2tp/l2tp_core.c

@@ -1072,7 +1072,7 @@ int l2tp_xmit_skb(struct l2tp_session *session, struct sk_buff *skb, int hdr_len
 
 
 	/* Get routing info from the tunnel socket */
 	/* Get routing info from the tunnel socket */
 	skb_dst_drop(skb);
 	skb_dst_drop(skb);
-	skb_dst_set(skb, dst_clone(__sk_dst_get(sk)));
+	skb_dst_set(skb, dst_clone(__sk_dst_check(sk, 0)));
 
 
 	inet = inet_sk(sk);
 	inet = inet_sk(sk);
 	fl = &inet->cork.fl;
 	fl = &inet->cork.fl;

+ 39 - 3
net/mac80211/agg-tx.c

@@ -161,6 +161,12 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 		return -ENOENT;
 		return -ENOENT;
 	}
 	}
 
 
+	/* if we're already stopping ignore any new requests to stop */
+	if (test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
+		spin_unlock_bh(&sta->lock);
+		return -EALREADY;
+	}
+
 	if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
 	if (test_bit(HT_AGG_STATE_WANT_START, &tid_tx->state)) {
 		/* not even started yet! */
 		/* not even started yet! */
 		ieee80211_assign_tid_tx(sta, tid, NULL);
 		ieee80211_assign_tid_tx(sta, tid, NULL);
@@ -169,6 +175,8 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 		return 0;
 		return 0;
 	}
 	}
 
 
+	set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
+
 	spin_unlock_bh(&sta->lock);
 	spin_unlock_bh(&sta->lock);
 
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
 #ifdef CONFIG_MAC80211_HT_DEBUG
@@ -176,8 +184,6 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 	       sta->sta.addr, tid);
 	       sta->sta.addr, tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
 #endif /* CONFIG_MAC80211_HT_DEBUG */
 
 
-	set_bit(HT_AGG_STATE_STOPPING, &tid_tx->state);
-
 	del_timer_sync(&tid_tx->addba_resp_timer);
 	del_timer_sync(&tid_tx->addba_resp_timer);
 
 
 	/*
 	/*
@@ -187,6 +193,20 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 	 */
 	 */
 	clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
 	clear_bit(HT_AGG_STATE_OPERATIONAL, &tid_tx->state);
 
 
+	/*
+	 * There might be a few packets being processed right now (on
+	 * another CPU) that have already gotten past the aggregation
+	 * check when it was still OPERATIONAL and consequently have
+	 * IEEE80211_TX_CTL_AMPDU set. In that case, this code might
+	 * call into the driver at the same time or even before the
+	 * TX paths calls into it, which could confuse the driver.
+	 *
+	 * Wait for all currently running TX paths to finish before
+	 * telling the driver. New packets will not go through since
+	 * the aggregation session is no longer OPERATIONAL.
+	 */
+	synchronize_net();
+
 	tid_tx->stop_initiator = initiator;
 	tid_tx->stop_initiator = initiator;
 	tid_tx->tx_stop = tx;
 	tid_tx->tx_stop = tx;
 
 
@@ -757,11 +777,27 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	del_timer(&tid_tx->addba_resp_timer);
+	del_timer_sync(&tid_tx->addba_resp_timer);
 
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
 #ifdef CONFIG_MAC80211_HT_DEBUG
 	printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
 	printk(KERN_DEBUG "switched off addBA timer for tid %d\n", tid);
 #endif
 #endif
+
+	/*
+	 * addba_resp_timer may have fired before we got here, and
+	 * caused WANT_STOP to be set. If the stop then was already
+	 * processed further, STOPPING might be set.
+	 */
+	if (test_bit(HT_AGG_STATE_WANT_STOP, &tid_tx->state) ||
+	    test_bit(HT_AGG_STATE_STOPPING, &tid_tx->state)) {
+#ifdef CONFIG_MAC80211_HT_DEBUG
+		printk(KERN_DEBUG
+		       "got addBA resp for tid %d but we already gave up\n",
+		       tid);
+#endif
+		goto out;
+	}
+
 	/*
 	/*
 	 * IEEE 802.11-2007 7.3.1.14:
 	 * IEEE 802.11-2007 7.3.1.14:
 	 * In an ADDBA Response frame, when the Status Code field
 	 * In an ADDBA Response frame, when the Status Code field

+ 2 - 2
net/mac80211/debugfs_sta.c

@@ -274,9 +274,9 @@ static ssize_t sta_ht_capa_read(struct file *file, char __user *userbuf,
 
 
 		PRINT_HT_CAP((htc->cap & BIT(10)), "HT Delayed Block Ack");
 		PRINT_HT_CAP((htc->cap & BIT(10)), "HT Delayed Block Ack");
 
 
-		PRINT_HT_CAP((htc->cap & BIT(11)), "Max AMSDU length: "
-			     "3839 bytes");
 		PRINT_HT_CAP(!(htc->cap & BIT(11)), "Max AMSDU length: "
 		PRINT_HT_CAP(!(htc->cap & BIT(11)), "Max AMSDU length: "
+			     "3839 bytes");
+		PRINT_HT_CAP((htc->cap & BIT(11)), "Max AMSDU length: "
 			     "7935 bytes");
 			     "7935 bytes");
 
 
 		/*
 		/*

+ 4 - 4
net/mac80211/status.c

@@ -260,7 +260,7 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
 	struct ieee80211_radiotap_header *rthdr;
 	struct ieee80211_radiotap_header *rthdr;
 	unsigned char *pos;
 	unsigned char *pos;
-	__le16 txflags;
+	u16 txflags;
 
 
 	rthdr = (struct ieee80211_radiotap_header *) skb_push(skb, rtap_len);
 	rthdr = (struct ieee80211_radiotap_header *) skb_push(skb, rtap_len);
 
 
@@ -290,13 +290,13 @@ static void ieee80211_add_tx_radiotap_header(struct ieee80211_supported_band
 	txflags = 0;
 	txflags = 0;
 	if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
 	if (!(info->flags & IEEE80211_TX_STAT_ACK) &&
 	    !is_multicast_ether_addr(hdr->addr1))
 	    !is_multicast_ether_addr(hdr->addr1))
-		txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_FAIL);
+		txflags |= IEEE80211_RADIOTAP_F_TX_FAIL;
 
 
 	if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
 	if ((info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) ||
 	    (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
 	    (info->status.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT))
-		txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_CTS);
+		txflags |= IEEE80211_RADIOTAP_F_TX_CTS;
 	else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
 	else if (info->status.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS)
-		txflags |= cpu_to_le16(IEEE80211_RADIOTAP_F_TX_RTS);
+		txflags |= IEEE80211_RADIOTAP_F_TX_RTS;
 
 
 	put_unaligned_le16(txflags, pos);
 	put_unaligned_le16(txflags, pos);
 	pos += 2;
 	pos += 2;

+ 0 - 2
net/netfilter/Kconfig

@@ -201,7 +201,6 @@ config NF_CONNTRACK_BROADCAST
 
 
 config NF_CONNTRACK_NETBIOS_NS
 config NF_CONNTRACK_NETBIOS_NS
 	tristate "NetBIOS name service protocol support"
 	tristate "NetBIOS name service protocol support"
-	depends on NETFILTER_ADVANCED
 	select NF_CONNTRACK_BROADCAST
 	select NF_CONNTRACK_BROADCAST
 	help
 	help
 	  NetBIOS name service requests are sent as broadcast messages from an
 	  NetBIOS name service requests are sent as broadcast messages from an
@@ -542,7 +541,6 @@ config NETFILTER_XT_TARGET_NOTRACK
 	tristate  '"NOTRACK" target support'
 	tristate  '"NOTRACK" target support'
 	depends on IP_NF_RAW || IP6_NF_RAW
 	depends on IP_NF_RAW || IP6_NF_RAW
 	depends on NF_CONNTRACK
 	depends on NF_CONNTRACK
-	depends on NETFILTER_ADVANCED
 	help
 	help
 	  The NOTRACK target allows a select rule to specify
 	  The NOTRACK target allows a select rule to specify
 	  which packets *not* to enter the conntrack/NAT
 	  which packets *not* to enter the conntrack/NAT

+ 1 - 1
net/netfilter/ipset/ip_set_hash_ipport.c

@@ -158,7 +158,7 @@ hash_ipport4_uadt(struct ip_set *set, struct nlattr *tb[],
 	const struct ip_set_hash *h = set->data;
 	const struct ip_set_hash *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_ipport4_elem data = { };
 	struct hash_ipport4_elem data = { };
-	u32 ip, ip_to, p = 0, port, port_to;
+	u32 ip, ip_to = 0, p = 0, port, port_to;
 	u32 timeout = h->timeout;
 	u32 timeout = h->timeout;
 	bool with_ports = false;
 	bool with_ports = false;
 	int ret;
 	int ret;

+ 1 - 1
net/netfilter/ipset/ip_set_hash_ipportip.c

@@ -162,7 +162,7 @@ hash_ipportip4_uadt(struct ip_set *set, struct nlattr *tb[],
 	const struct ip_set_hash *h = set->data;
 	const struct ip_set_hash *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_ipportip4_elem data = { };
 	struct hash_ipportip4_elem data = { };
-	u32 ip, ip_to, p = 0, port, port_to;
+	u32 ip, ip_to = 0, p = 0, port, port_to;
 	u32 timeout = h->timeout;
 	u32 timeout = h->timeout;
 	bool with_ports = false;
 	bool with_ports = false;
 	int ret;
 	int ret;

+ 1 - 1
net/netfilter/ipset/ip_set_hash_ipportnet.c

@@ -184,7 +184,7 @@ hash_ipportnet4_uadt(struct ip_set *set, struct nlattr *tb[],
 	const struct ip_set_hash *h = set->data;
 	const struct ip_set_hash *h = set->data;
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	ipset_adtfn adtfn = set->variant->adt[adt];
 	struct hash_ipportnet4_elem data = { .cidr = HOST_MASK };
 	struct hash_ipportnet4_elem data = { .cidr = HOST_MASK };
-	u32 ip, ip_to, p = 0, port, port_to;
+	u32 ip, ip_to = 0, p = 0, port, port_to;
 	u32 ip2_from = 0, ip2_to, ip2_last, ip2;
 	u32 ip2_from = 0, ip2_to, ip2_last, ip2;
 	u32 timeout = h->timeout;
 	u32 timeout = h->timeout;
 	bool with_ports = false;
 	bool with_ports = false;

+ 18 - 19
net/netfilter/nf_conntrack_ecache.c

@@ -27,22 +27,17 @@
 
 
 static DEFINE_MUTEX(nf_ct_ecache_mutex);
 static DEFINE_MUTEX(nf_ct_ecache_mutex);
 
 
-struct nf_ct_event_notifier __rcu *nf_conntrack_event_cb __read_mostly;
-EXPORT_SYMBOL_GPL(nf_conntrack_event_cb);
-
-struct nf_exp_event_notifier __rcu *nf_expect_event_cb __read_mostly;
-EXPORT_SYMBOL_GPL(nf_expect_event_cb);
-
 /* deliver cached events and clear cache entry - must be called with locally
 /* deliver cached events and clear cache entry - must be called with locally
  * disabled softirqs */
  * disabled softirqs */
 void nf_ct_deliver_cached_events(struct nf_conn *ct)
 void nf_ct_deliver_cached_events(struct nf_conn *ct)
 {
 {
+	struct net *net = nf_ct_net(ct);
 	unsigned long events;
 	unsigned long events;
 	struct nf_ct_event_notifier *notify;
 	struct nf_ct_event_notifier *notify;
 	struct nf_conntrack_ecache *e;
 	struct nf_conntrack_ecache *e;
 
 
 	rcu_read_lock();
 	rcu_read_lock();
-	notify = rcu_dereference(nf_conntrack_event_cb);
+	notify = rcu_dereference(net->ct.nf_conntrack_event_cb);
 	if (notify == NULL)
 	if (notify == NULL)
 		goto out_unlock;
 		goto out_unlock;
 
 
@@ -83,19 +78,20 @@ out_unlock:
 }
 }
 EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
 EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
 
 
-int nf_conntrack_register_notifier(struct nf_ct_event_notifier *new)
+int nf_conntrack_register_notifier(struct net *net,
+				   struct nf_ct_event_notifier *new)
 {
 {
 	int ret = 0;
 	int ret = 0;
 	struct nf_ct_event_notifier *notify;
 	struct nf_ct_event_notifier *notify;
 
 
 	mutex_lock(&nf_ct_ecache_mutex);
 	mutex_lock(&nf_ct_ecache_mutex);
-	notify = rcu_dereference_protected(nf_conntrack_event_cb,
+	notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
 					   lockdep_is_held(&nf_ct_ecache_mutex));
 					   lockdep_is_held(&nf_ct_ecache_mutex));
 	if (notify != NULL) {
 	if (notify != NULL) {
 		ret = -EBUSY;
 		ret = -EBUSY;
 		goto out_unlock;
 		goto out_unlock;
 	}
 	}
-	RCU_INIT_POINTER(nf_conntrack_event_cb, new);
+	RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, new);
 	mutex_unlock(&nf_ct_ecache_mutex);
 	mutex_unlock(&nf_ct_ecache_mutex);
 	return ret;
 	return ret;
 
 
@@ -105,32 +101,34 @@ out_unlock:
 }
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
 EXPORT_SYMBOL_GPL(nf_conntrack_register_notifier);
 
 
-void nf_conntrack_unregister_notifier(struct nf_ct_event_notifier *new)
+void nf_conntrack_unregister_notifier(struct net *net,
+				      struct nf_ct_event_notifier *new)
 {
 {
 	struct nf_ct_event_notifier *notify;
 	struct nf_ct_event_notifier *notify;
 
 
 	mutex_lock(&nf_ct_ecache_mutex);
 	mutex_lock(&nf_ct_ecache_mutex);
-	notify = rcu_dereference_protected(nf_conntrack_event_cb,
+	notify = rcu_dereference_protected(net->ct.nf_conntrack_event_cb,
 					   lockdep_is_held(&nf_ct_ecache_mutex));
 					   lockdep_is_held(&nf_ct_ecache_mutex));
 	BUG_ON(notify != new);
 	BUG_ON(notify != new);
-	RCU_INIT_POINTER(nf_conntrack_event_cb, NULL);
+	RCU_INIT_POINTER(net->ct.nf_conntrack_event_cb, NULL);
 	mutex_unlock(&nf_ct_ecache_mutex);
 	mutex_unlock(&nf_ct_ecache_mutex);
 }
 }
 EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
 EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
 
 
-int nf_ct_expect_register_notifier(struct nf_exp_event_notifier *new)
+int nf_ct_expect_register_notifier(struct net *net,
+				   struct nf_exp_event_notifier *new)
 {
 {
 	int ret = 0;
 	int ret = 0;
 	struct nf_exp_event_notifier *notify;
 	struct nf_exp_event_notifier *notify;
 
 
 	mutex_lock(&nf_ct_ecache_mutex);
 	mutex_lock(&nf_ct_ecache_mutex);
-	notify = rcu_dereference_protected(nf_expect_event_cb,
+	notify = rcu_dereference_protected(net->ct.nf_expect_event_cb,
 					   lockdep_is_held(&nf_ct_ecache_mutex));
 					   lockdep_is_held(&nf_ct_ecache_mutex));
 	if (notify != NULL) {
 	if (notify != NULL) {
 		ret = -EBUSY;
 		ret = -EBUSY;
 		goto out_unlock;
 		goto out_unlock;
 	}
 	}
-	RCU_INIT_POINTER(nf_expect_event_cb, new);
+	RCU_INIT_POINTER(net->ct.nf_expect_event_cb, new);
 	mutex_unlock(&nf_ct_ecache_mutex);
 	mutex_unlock(&nf_ct_ecache_mutex);
 	return ret;
 	return ret;
 
 
@@ -140,15 +138,16 @@ out_unlock:
 }
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
 EXPORT_SYMBOL_GPL(nf_ct_expect_register_notifier);
 
 
-void nf_ct_expect_unregister_notifier(struct nf_exp_event_notifier *new)
+void nf_ct_expect_unregister_notifier(struct net *net,
+				      struct nf_exp_event_notifier *new)
 {
 {
 	struct nf_exp_event_notifier *notify;
 	struct nf_exp_event_notifier *notify;
 
 
 	mutex_lock(&nf_ct_ecache_mutex);
 	mutex_lock(&nf_ct_ecache_mutex);
-	notify = rcu_dereference_protected(nf_expect_event_cb,
+	notify = rcu_dereference_protected(net->ct.nf_expect_event_cb,
 					   lockdep_is_held(&nf_ct_ecache_mutex));
 					   lockdep_is_held(&nf_ct_ecache_mutex));
 	BUG_ON(notify != new);
 	BUG_ON(notify != new);
-	RCU_INIT_POINTER(nf_expect_event_cb, NULL);
+	RCU_INIT_POINTER(net->ct.nf_expect_event_cb, NULL);
 	mutex_unlock(&nf_ct_ecache_mutex);
 	mutex_unlock(&nf_ct_ecache_mutex);
 }
 }
 EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);
 EXPORT_SYMBOL_GPL(nf_ct_expect_unregister_notifier);

+ 52 - 21
net/netfilter/nf_conntrack_netlink.c

@@ -4,7 +4,7 @@
  * (C) 2001 by Jay Schulist <jschlst@samba.org>
  * (C) 2001 by Jay Schulist <jschlst@samba.org>
  * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
  * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
  * (C) 2003 by Patrick Mchardy <kaber@trash.net>
  * (C) 2003 by Patrick Mchardy <kaber@trash.net>
- * (C) 2005-2008 by Pablo Neira Ayuso <pablo@netfilter.org>
+ * (C) 2005-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
  *
  *
  * Initial connection tracking via netlink development funded and
  * Initial connection tracking via netlink development funded and
  * generally made possible by Network Robots, Inc. (www.networkrobots.com)
  * generally made possible by Network Robots, Inc. (www.networkrobots.com)
@@ -2163,6 +2163,54 @@ MODULE_ALIAS("ip_conntrack_netlink");
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK);
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_CTNETLINK_EXP);
 
 
+static int __net_init ctnetlink_net_init(struct net *net)
+{
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+	int ret;
+
+	ret = nf_conntrack_register_notifier(net, &ctnl_notifier);
+	if (ret < 0) {
+		pr_err("ctnetlink_init: cannot register notifier.\n");
+		goto err_out;
+	}
+
+	ret = nf_ct_expect_register_notifier(net, &ctnl_notifier_exp);
+	if (ret < 0) {
+		pr_err("ctnetlink_init: cannot expect register notifier.\n");
+		goto err_unreg_notifier;
+	}
+#endif
+	return 0;
+
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+err_unreg_notifier:
+	nf_conntrack_unregister_notifier(net, &ctnl_notifier);
+err_out:
+	return ret;
+#endif
+}
+
+static void ctnetlink_net_exit(struct net *net)
+{
+#ifdef CONFIG_NF_CONNTRACK_EVENTS
+	nf_ct_expect_unregister_notifier(net, &ctnl_notifier_exp);
+	nf_conntrack_unregister_notifier(net, &ctnl_notifier);
+#endif
+}
+
+static void __net_exit ctnetlink_net_exit_batch(struct list_head *net_exit_list)
+{
+	struct net *net;
+
+	list_for_each_entry(net, net_exit_list, exit_list)
+		ctnetlink_net_exit(net);
+}
+
+static struct pernet_operations ctnetlink_net_ops = {
+	.init		= ctnetlink_net_init,
+	.exit_batch	= ctnetlink_net_exit_batch,
+};
+
 static int __init ctnetlink_init(void)
 static int __init ctnetlink_init(void)
 {
 {
 	int ret;
 	int ret;
@@ -2180,28 +2228,15 @@ static int __init ctnetlink_init(void)
 		goto err_unreg_subsys;
 		goto err_unreg_subsys;
 	}
 	}
 
 
-#ifdef CONFIG_NF_CONNTRACK_EVENTS
-	ret = nf_conntrack_register_notifier(&ctnl_notifier);
-	if (ret < 0) {
-		pr_err("ctnetlink_init: cannot register notifier.\n");
+	if (register_pernet_subsys(&ctnetlink_net_ops)) {
+		pr_err("ctnetlink_init: cannot register pernet operations\n");
 		goto err_unreg_exp_subsys;
 		goto err_unreg_exp_subsys;
 	}
 	}
 
 
-	ret = nf_ct_expect_register_notifier(&ctnl_notifier_exp);
-	if (ret < 0) {
-		pr_err("ctnetlink_init: cannot expect register notifier.\n");
-		goto err_unreg_notifier;
-	}
-#endif
-
 	return 0;
 	return 0;
 
 
-#ifdef CONFIG_NF_CONNTRACK_EVENTS
-err_unreg_notifier:
-	nf_conntrack_unregister_notifier(&ctnl_notifier);
 err_unreg_exp_subsys:
 err_unreg_exp_subsys:
 	nfnetlink_subsys_unregister(&ctnl_exp_subsys);
 	nfnetlink_subsys_unregister(&ctnl_exp_subsys);
-#endif
 err_unreg_subsys:
 err_unreg_subsys:
 	nfnetlink_subsys_unregister(&ctnl_subsys);
 	nfnetlink_subsys_unregister(&ctnl_subsys);
 err_out:
 err_out:
@@ -2213,11 +2248,7 @@ static void __exit ctnetlink_exit(void)
 	pr_info("ctnetlink: unregistering from nfnetlink.\n");
 	pr_info("ctnetlink: unregistering from nfnetlink.\n");
 
 
 	nf_ct_remove_userspace_expectations();
 	nf_ct_remove_userspace_expectations();
-#ifdef CONFIG_NF_CONNTRACK_EVENTS
-	nf_ct_expect_unregister_notifier(&ctnl_notifier_exp);
-	nf_conntrack_unregister_notifier(&ctnl_notifier);
-#endif
-
+	unregister_pernet_subsys(&ctnetlink_net_ops);
 	nfnetlink_subsys_unregister(&ctnl_exp_subsys);
 	nfnetlink_subsys_unregister(&ctnl_exp_subsys);
 	nfnetlink_subsys_unregister(&ctnl_subsys);
 	nfnetlink_subsys_unregister(&ctnl_subsys);
 }
 }

+ 16 - 10
net/netlabel/netlabel_kapi.c

@@ -111,8 +111,6 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
 	struct netlbl_domaddr_map *addrmap = NULL;
 	struct netlbl_domaddr_map *addrmap = NULL;
 	struct netlbl_domaddr4_map *map4 = NULL;
 	struct netlbl_domaddr4_map *map4 = NULL;
 	struct netlbl_domaddr6_map *map6 = NULL;
 	struct netlbl_domaddr6_map *map6 = NULL;
-	const struct in_addr *addr4, *mask4;
-	const struct in6_addr *addr6, *mask6;
 
 
 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
 	entry = kzalloc(sizeof(*entry), GFP_ATOMIC);
 	if (entry == NULL)
 	if (entry == NULL)
@@ -133,9 +131,9 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
 		INIT_LIST_HEAD(&addrmap->list6);
 		INIT_LIST_HEAD(&addrmap->list6);
 
 
 		switch (family) {
 		switch (family) {
-		case AF_INET:
-			addr4 = addr;
-			mask4 = mask;
+		case AF_INET: {
+			const struct in_addr *addr4 = addr;
+			const struct in_addr *mask4 = mask;
 			map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
 			map4 = kzalloc(sizeof(*map4), GFP_ATOMIC);
 			if (map4 == NULL)
 			if (map4 == NULL)
 				goto cfg_unlbl_map_add_failure;
 				goto cfg_unlbl_map_add_failure;
@@ -148,9 +146,11 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
 			if (ret_val != 0)
 			if (ret_val != 0)
 				goto cfg_unlbl_map_add_failure;
 				goto cfg_unlbl_map_add_failure;
 			break;
 			break;
-		case AF_INET6:
-			addr6 = addr;
-			mask6 = mask;
+			}
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
+		case AF_INET6: {
+			const struct in6_addr *addr6 = addr;
+			const struct in6_addr *mask6 = mask;
 			map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
 			map6 = kzalloc(sizeof(*map6), GFP_ATOMIC);
 			if (map6 == NULL)
 			if (map6 == NULL)
 				goto cfg_unlbl_map_add_failure;
 				goto cfg_unlbl_map_add_failure;
@@ -162,11 +162,13 @@ int netlbl_cfg_unlbl_map_add(const char *domain,
 			map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
 			map6->list.addr.s6_addr32[3] &= mask6->s6_addr32[3];
 			ipv6_addr_copy(&map6->list.mask, mask6);
 			ipv6_addr_copy(&map6->list.mask, mask6);
 			map6->list.valid = 1;
 			map6->list.valid = 1;
-			ret_val = netlbl_af4list_add(&map4->list,
-						     &addrmap->list4);
+			ret_val = netlbl_af6list_add(&map6->list,
+						     &addrmap->list6);
 			if (ret_val != 0)
 			if (ret_val != 0)
 				goto cfg_unlbl_map_add_failure;
 				goto cfg_unlbl_map_add_failure;
 			break;
 			break;
+			}
+#endif /* IPv6 */
 		default:
 		default:
 			goto cfg_unlbl_map_add_failure;
 			goto cfg_unlbl_map_add_failure;
 			break;
 			break;
@@ -225,9 +227,11 @@ int netlbl_cfg_unlbl_static_add(struct net *net,
 	case AF_INET:
 	case AF_INET:
 		addr_len = sizeof(struct in_addr);
 		addr_len = sizeof(struct in_addr);
 		break;
 		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case AF_INET6:
 	case AF_INET6:
 		addr_len = sizeof(struct in6_addr);
 		addr_len = sizeof(struct in6_addr);
 		break;
 		break;
+#endif /* IPv6 */
 	default:
 	default:
 		return -EPFNOSUPPORT;
 		return -EPFNOSUPPORT;
 	}
 	}
@@ -266,9 +270,11 @@ int netlbl_cfg_unlbl_static_del(struct net *net,
 	case AF_INET:
 	case AF_INET:
 		addr_len = sizeof(struct in_addr);
 		addr_len = sizeof(struct in_addr);
 		break;
 		break;
+#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
 	case AF_INET6:
 	case AF_INET6:
 		addr_len = sizeof(struct in6_addr);
 		addr_len = sizeof(struct in6_addr);
 		break;
 		break;
+#endif /* IPv6 */
 	default:
 	default:
 		return -EPFNOSUPPORT;
 		return -EPFNOSUPPORT;
 	}
 	}

+ 2 - 2
net/sched/sch_red.c

@@ -209,8 +209,8 @@ static int red_change(struct Qdisc *sch, struct nlattr *opt)
 				 ctl->Plog, ctl->Scell_log,
 				 ctl->Plog, ctl->Scell_log,
 				 nla_data(tb[TCA_RED_STAB]));
 				 nla_data(tb[TCA_RED_STAB]));
 
 
-	if (skb_queue_empty(&sch->q))
-		red_end_of_idle_period(&q->parms);
+	if (!q->qdisc->q.qlen)
+		red_start_of_idle_period(&q->parms);
 
 
 	sch_tree_unlock(sch);
 	sch_tree_unlock(sch);
 	return 0;
 	return 0;

+ 20 - 11
net/sched/sch_teql.c

@@ -225,11 +225,11 @@ static int teql_qdisc_init(struct Qdisc *sch, struct nlattr *opt)
 
 
 
 
 static int
 static int
-__teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *dev)
+__teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res,
+	       struct net_device *dev, struct netdev_queue *txq,
+	       struct neighbour *mn)
 {
 {
-	struct netdev_queue *dev_queue = netdev_get_tx_queue(dev, 0);
-	struct teql_sched_data *q = qdisc_priv(dev_queue->qdisc);
-	struct neighbour *mn = dst_get_neighbour(skb_dst(skb));
+	struct teql_sched_data *q = qdisc_priv(txq->qdisc);
 	struct neighbour *n = q->ncache;
 	struct neighbour *n = q->ncache;
 
 
 	if (mn->tbl == NULL)
 	if (mn->tbl == NULL)
@@ -262,17 +262,26 @@ __teql_resolve(struct sk_buff *skb, struct sk_buff *skb_res, struct net_device *
 }
 }
 
 
 static inline int teql_resolve(struct sk_buff *skb,
 static inline int teql_resolve(struct sk_buff *skb,
-			       struct sk_buff *skb_res, struct net_device *dev)
+			       struct sk_buff *skb_res,
+			       struct net_device *dev,
+			       struct netdev_queue *txq)
 {
 {
-	struct netdev_queue *txq = netdev_get_tx_queue(dev, 0);
+	struct dst_entry *dst = skb_dst(skb);
+	struct neighbour *mn;
+	int res;
+
 	if (txq->qdisc == &noop_qdisc)
 	if (txq->qdisc == &noop_qdisc)
 		return -ENODEV;
 		return -ENODEV;
 
 
-	if (dev->header_ops == NULL ||
-	    skb_dst(skb) == NULL ||
-	    dst_get_neighbour(skb_dst(skb)) == NULL)
+	if (!dev->header_ops || !dst)
 		return 0;
 		return 0;
-	return __teql_resolve(skb, skb_res, dev);
+
+	rcu_read_lock();
+	mn = dst_get_neighbour(dst);
+	res = mn ? __teql_resolve(skb, skb_res, dev, txq, mn) : 0;
+	rcu_read_unlock();
+
+	return res;
 }
 }
 
 
 static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
 static netdev_tx_t teql_master_xmit(struct sk_buff *skb, struct net_device *dev)
@@ -307,7 +316,7 @@ restart:
 			continue;
 			continue;
 		}
 		}
 
 
-		switch (teql_resolve(skb, skb_res, slave)) {
+		switch (teql_resolve(skb, skb_res, slave, slave_txq)) {
 		case 0:
 		case 0:
 			if (__netif_tx_trylock(slave_txq)) {
 			if (__netif_tx_trylock(slave_txq)) {
 				unsigned int length = qdisc_pkt_len(skb);
 				unsigned int length = qdisc_pkt_len(skb);

+ 1 - 1
net/sctp/auth.c

@@ -82,7 +82,7 @@ static struct sctp_auth_bytes *sctp_auth_create_key(__u32 key_len, gfp_t gfp)
 	struct sctp_auth_bytes *key;
 	struct sctp_auth_bytes *key;
 
 
 	/* Verify that we are not going to overflow INT_MAX */
 	/* Verify that we are not going to overflow INT_MAX */
-	if ((INT_MAX - key_len) < sizeof(struct sctp_auth_bytes))
+	if (key_len > (INT_MAX - sizeof(struct sctp_auth_bytes)))
 		return NULL;
 		return NULL;
 
 
 	/* Allocate the shared key */
 	/* Allocate the shared key */

+ 4 - 0
net/unix/af_unix.c

@@ -1957,6 +1957,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 			if ((UNIXCB(skb).pid  != siocb->scm->pid) ||
 			if ((UNIXCB(skb).pid  != siocb->scm->pid) ||
 			    (UNIXCB(skb).cred != siocb->scm->cred)) {
 			    (UNIXCB(skb).cred != siocb->scm->cred)) {
 				skb_queue_head(&sk->sk_receive_queue, skb);
 				skb_queue_head(&sk->sk_receive_queue, skb);
+				sk->sk_data_ready(sk, skb->len);
 				break;
 				break;
 			}
 			}
 		} else {
 		} else {
@@ -1974,6 +1975,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 		chunk = min_t(unsigned int, skb->len, size);
 		chunk = min_t(unsigned int, skb->len, size);
 		if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
 		if (memcpy_toiovec(msg->msg_iov, skb->data, chunk)) {
 			skb_queue_head(&sk->sk_receive_queue, skb);
 			skb_queue_head(&sk->sk_receive_queue, skb);
+			sk->sk_data_ready(sk, skb->len);
 			if (copied == 0)
 			if (copied == 0)
 				copied = -EFAULT;
 				copied = -EFAULT;
 			break;
 			break;
@@ -1991,6 +1993,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 			/* put the skb back if we didn't use it up.. */
 			/* put the skb back if we didn't use it up.. */
 			if (skb->len) {
 			if (skb->len) {
 				skb_queue_head(&sk->sk_receive_queue, skb);
 				skb_queue_head(&sk->sk_receive_queue, skb);
+				sk->sk_data_ready(sk, skb->len);
 				break;
 				break;
 			}
 			}
 
 
@@ -2006,6 +2009,7 @@ static int unix_stream_recvmsg(struct kiocb *iocb, struct socket *sock,
 
 
 			/* put message back and return */
 			/* put message back and return */
 			skb_queue_head(&sk->sk_receive_queue, skb);
 			skb_queue_head(&sk->sk_receive_queue, skb);
+			sk->sk_data_ready(sk, skb->len);
 			break;
 			break;
 		}
 		}
 	} while (size);
 	} while (size);

+ 2 - 2
net/wireless/nl80211.c

@@ -89,8 +89,8 @@ static const struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] = {
 	[NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
 	[NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
 	[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
 	[NL80211_ATTR_IFNAME] = { .type = NLA_NUL_STRING, .len = IFNAMSIZ-1 },
 
 
-	[NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
-	[NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN },
+	[NL80211_ATTR_MAC] = { .len = ETH_ALEN },
+	[NL80211_ATTR_PREV_BSSID] = { .len = ETH_ALEN },
 
 
 	[NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
 	[NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
 	[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
 	[NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,

+ 4 - 0
net/wireless/reg.c

@@ -2037,6 +2037,10 @@ static int __set_regdom(const struct ieee80211_regdomain *rd)
 	}
 	}
 
 
 	request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
 	request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
+	if (!request_wiphy) {
+		reg_set_request_processed();
+		return -ENODEV;
+	}
 
 
 	if (!last_request->intersect) {
 	if (!last_request->intersect) {
 		int r;
 		int r;

+ 6 - 4
net/xfrm/xfrm_policy.c

@@ -2382,9 +2382,11 @@ static unsigned int xfrm_default_advmss(const struct dst_entry *dst)
 	return dst_metric_advmss(dst->path);
 	return dst_metric_advmss(dst->path);
 }
 }
 
 
-static unsigned int xfrm_default_mtu(const struct dst_entry *dst)
+static unsigned int xfrm_mtu(const struct dst_entry *dst)
 {
 {
-	return dst_mtu(dst->path);
+	unsigned int mtu = dst_metric_raw(dst, RTAX_MTU);
+
+	return mtu ? : dst_mtu(dst->path);
 }
 }
 
 
 static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, const void *daddr)
 static struct neighbour *xfrm_neigh_lookup(const struct dst_entry *dst, const void *daddr)
@@ -2411,8 +2413,8 @@ int xfrm_policy_register_afinfo(struct xfrm_policy_afinfo *afinfo)
 			dst_ops->check = xfrm_dst_check;
 			dst_ops->check = xfrm_dst_check;
 		if (likely(dst_ops->default_advmss == NULL))
 		if (likely(dst_ops->default_advmss == NULL))
 			dst_ops->default_advmss = xfrm_default_advmss;
 			dst_ops->default_advmss = xfrm_default_advmss;
-		if (likely(dst_ops->default_mtu == NULL))
-			dst_ops->default_mtu = xfrm_default_mtu;
+		if (likely(dst_ops->mtu == NULL))
+			dst_ops->mtu = xfrm_mtu;
 		if (likely(dst_ops->negative_advice == NULL))
 		if (likely(dst_ops->negative_advice == NULL))
 			dst_ops->negative_advice = xfrm_negative_advice;
 			dst_ops->negative_advice = xfrm_negative_advice;
 		if (likely(dst_ops->link_failure == NULL))
 		if (likely(dst_ops->link_failure == NULL))