浏览代码

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

* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [IPV4/IPV6]: Fix inet{,6} device initialization order.
  [TCP]: Use old definition of before
  [NETFILTER]: ebtables: don't compute gap before checking struct type
  [NETFILTER]: nf_nat: fix MASQUERADE crash on device down
  [NETFILTER]: New connection tracking is not EXPERIMENTAL anymore
  [NETFILTER]: Fix routing of REJECT target generated packets in output chain
  [NETFILTER]: compat offsets size change
  [SUNGEM]: PHY updates & pause fixes (#2)
  [X25]: proper prototype for x25_init_timers()
  [AF_NETLINK]: module_put cleanup
  [XFRM_USER]: avoid pointless void ** casts
  [NETFILTER] xt_hashlimit.c: fix typo
  [NET] drivers/net/loopback.c: convert to module_init()
  [PKTGEN]: Convert to kthread API.
  [NET]: ifb double-counts packets
Linus Torvalds 18 年之前
父节点
当前提交
8be7ed14f4

+ 0 - 11
drivers/net/Space.c

@@ -349,22 +349,11 @@ static void __init trif_probe2(int unit)
 #endif
 #endif
 
 
 
 
-/*
- *	The loopback device is global so it can be directly referenced
- *	by the network code. Also, it must be first on device list.
- */
-extern int loopback_init(void);
-
 /*  Statically configured drivers -- order matters here. */
 /*  Statically configured drivers -- order matters here. */
 static int __init net_olddevs_init(void)
 static int __init net_olddevs_init(void)
 {
 {
 	int num;
 	int num;
 
 
-	if (loopback_init()) {
-		printk(KERN_ERR "Network loopback device setup failed\n");
-	}
-
-
 #ifdef CONFIG_SBNI
 #ifdef CONFIG_SBNI
 	for (num = 0; num < 8; ++num)
 	for (num = 0; num < 8; ++num)
 		sbni_probe(num);
 		sbni_probe(num);

+ 2 - 2
drivers/net/ifb.c

@@ -154,8 +154,8 @@ static int ifb_xmit(struct sk_buff *skb, struct net_device *dev)
 	int ret = 0;
 	int ret = 0;
 	u32 from = G_TC_FROM(skb->tc_verd);
 	u32 from = G_TC_FROM(skb->tc_verd);
 
 
-	stats->tx_packets++;
-	stats->tx_bytes+=skb->len;
+	stats->rx_packets++;
+	stats->rx_bytes+=skb->len;
 
 
 	if (!from || !skb->input_dev) {
 	if (!from || !skb->input_dev) {
 dropped:
 dropped:

+ 3 - 1
drivers/net/loopback.c

@@ -229,9 +229,11 @@ struct net_device loopback_dev = {
 };
 };
 
 
 /* Setup and register the loopback device. */
 /* Setup and register the loopback device. */
-int __init loopback_init(void)
+static int __init loopback_init(void)
 {
 {
 	return register_netdev(&loopback_dev);
 	return register_netdev(&loopback_dev);
 };
 };
 
 
+module_init(loopback_init);
+
 EXPORT_SYMBOL(loopback_dev);
 EXPORT_SYMBOL(loopback_dev);

+ 2 - 1
drivers/net/sungem.c

@@ -90,7 +90,8 @@
 
 
 #define ADVERTISE_MASK	(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
 #define ADVERTISE_MASK	(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
 			 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
 			 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
-			 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
+			 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full | \
+			 SUPPORTED_Pause | SUPPORTED_Autoneg)
 
 
 #define DRV_NAME	"sungem"
 #define DRV_NAME	"sungem"
 #define DRV_VERSION	"0.98"
 #define DRV_VERSION	"0.98"

+ 155 - 24
drivers/net/sungem_phy.c

@@ -3,10 +3,9 @@
  *
  *
  * This file could be shared with other drivers.
  * This file could be shared with other drivers.
  *
  *
- * (c) 2002, Benjamin Herrenscmidt (benh@kernel.crashing.org)
+ * (c) 2002-2007, Benjamin Herrenscmidt (benh@kernel.crashing.org)
  *
  *
  * TODO:
  * TODO:
- *  - Implement WOL
  *  - Add support for PHYs that provide an IRQ line
  *  - Add support for PHYs that provide an IRQ line
  *  - Eventually moved the entire polling state machine in
  *  - Eventually moved the entire polling state machine in
  *    there (out of the eth driver), so that it can easily be
  *    there (out of the eth driver), so that it can easily be
@@ -152,6 +151,44 @@ static int bcm5221_suspend(struct mii_phy* phy)
 	return 0;
 	return 0;
 }
 }
 
 
+static int bcm5241_init(struct mii_phy* phy)
+{
+	u16 data;
+
+	data = phy_read(phy, MII_BCM5221_TEST);
+	phy_write(phy, MII_BCM5221_TEST,
+		data | MII_BCM5221_TEST_ENABLE_SHADOWS);
+
+	data = phy_read(phy, MII_BCM5221_SHDOW_AUX_STAT2);
+	phy_write(phy, MII_BCM5221_SHDOW_AUX_STAT2,
+		data | MII_BCM5221_SHDOW_AUX_STAT2_APD);
+
+	data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4);
+	phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4,
+		data & ~MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR);
+
+	data = phy_read(phy, MII_BCM5221_TEST);
+	phy_write(phy, MII_BCM5221_TEST,
+		data & ~MII_BCM5221_TEST_ENABLE_SHADOWS);
+
+	return 0;
+}
+
+static int bcm5241_suspend(struct mii_phy* phy)
+{
+	u16 data;
+
+	data = phy_read(phy, MII_BCM5221_TEST);
+	phy_write(phy, MII_BCM5221_TEST,
+		data | MII_BCM5221_TEST_ENABLE_SHADOWS);
+
+	data = phy_read(phy, MII_BCM5221_SHDOW_AUX_MODE4);
+	phy_write(phy, MII_BCM5221_SHDOW_AUX_MODE4,
+		  data | MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR);
+
+	return 0;
+}
+
 static int bcm5400_init(struct mii_phy* phy)
 static int bcm5400_init(struct mii_phy* phy)
 {
 {
 	u16 data;
 	u16 data;
@@ -373,6 +410,10 @@ static int bcm54xx_setup_aneg(struct mii_phy *phy, u32 advertise)
 		adv |= ADVERTISE_100HALF;
 		adv |= ADVERTISE_100HALF;
 	if (advertise & ADVERTISED_100baseT_Full)
 	if (advertise & ADVERTISED_100baseT_Full)
 		adv |= ADVERTISE_100FULL;
 		adv |= ADVERTISE_100FULL;
+	if (advertise & ADVERTISED_Pause)
+		adv |= ADVERTISE_PAUSE_CAP;
+	if (advertise & ADVERTISED_Asym_Pause)
+		adv |= ADVERTISE_PAUSE_ASYM;
 	phy_write(phy, MII_ADVERTISE, adv);
 	phy_write(phy, MII_ADVERTISE, adv);
 
 
 	/* Setup 1000BT advertise */
 	/* Setup 1000BT advertise */
@@ -436,12 +477,15 @@ static int bcm54xx_read_link(struct mii_phy *phy)
 	    	val = phy_read(phy, MII_BCM5400_AUXSTATUS);
 	    	val = phy_read(phy, MII_BCM5400_AUXSTATUS);
 		link_mode = ((val & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >>
 		link_mode = ((val & MII_BCM5400_AUXSTATUS_LINKMODE_MASK) >>
 			     MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT);
 			     MII_BCM5400_AUXSTATUS_LINKMODE_SHIFT);
-		phy->duplex = phy_BCM5400_link_table[link_mode][0] ? DUPLEX_FULL : DUPLEX_HALF;
+		phy->duplex = phy_BCM5400_link_table[link_mode][0] ?
+			DUPLEX_FULL : DUPLEX_HALF;
 		phy->speed = phy_BCM5400_link_table[link_mode][2] ?
 		phy->speed = phy_BCM5400_link_table[link_mode][2] ?
 				SPEED_1000 :
 				SPEED_1000 :
-				(phy_BCM5400_link_table[link_mode][1] ? SPEED_100 : SPEED_10);
+				(phy_BCM5400_link_table[link_mode][1] ?
+				 SPEED_100 : SPEED_10);
 		val = phy_read(phy, MII_LPA);
 		val = phy_read(phy, MII_LPA);
-		phy->pause = ((val & LPA_PAUSE) != 0);
+		phy->pause = (phy->duplex == DUPLEX_FULL) &&
+			((val & LPA_PAUSE) != 0);
 	}
 	}
 	/* On non-aneg, we assume what we put in BMCR is the speed,
 	/* On non-aneg, we assume what we put in BMCR is the speed,
 	 * though magic-aneg shouldn't prevent this case from occurring
 	 * though magic-aneg shouldn't prevent this case from occurring
@@ -450,6 +494,28 @@ static int bcm54xx_read_link(struct mii_phy *phy)
 	return 0;
 	return 0;
 }
 }
 
 
+static int marvell88e1111_init(struct mii_phy* phy)
+{
+	u16 rev;
+
+	/* magic init sequence for rev 0 */
+	rev = phy_read(phy, MII_PHYSID2) & 0x000f;
+	if (rev == 0) {
+		phy_write(phy, 0x1d, 0x000a);
+		phy_write(phy, 0x1e, 0x0821);
+
+		phy_write(phy, 0x1d, 0x0006);
+		phy_write(phy, 0x1e, 0x8600);
+
+		phy_write(phy, 0x1d, 0x000b);
+		phy_write(phy, 0x1e, 0x0100);
+
+		phy_write(phy, 0x1d, 0x0004);
+		phy_write(phy, 0x1e, 0x4850);
+	}
+	return 0;
+}
+
 static int marvell_setup_aneg(struct mii_phy *phy, u32 advertise)
 static int marvell_setup_aneg(struct mii_phy *phy, u32 advertise)
 {
 {
 	u16 ctl, adv;
 	u16 ctl, adv;
@@ -471,6 +537,10 @@ static int marvell_setup_aneg(struct mii_phy *phy, u32 advertise)
 		adv |= ADVERTISE_100HALF;
 		adv |= ADVERTISE_100HALF;
 	if (advertise & ADVERTISED_100baseT_Full)
 	if (advertise & ADVERTISED_100baseT_Full)
 		adv |= ADVERTISE_100FULL;
 		adv |= ADVERTISE_100FULL;
+	if (advertise & ADVERTISED_Pause)
+		adv |= ADVERTISE_PAUSE_CAP;
+	if (advertise & ADVERTISED_Asym_Pause)
+		adv |= ADVERTISE_PAUSE_ASYM;
 	phy_write(phy, MII_ADVERTISE, adv);
 	phy_write(phy, MII_ADVERTISE, adv);
 
 
 	/* Setup 1000BT advertise & enable crossover detect
 	/* Setup 1000BT advertise & enable crossover detect
@@ -549,7 +619,7 @@ static int marvell_setup_forced(struct mii_phy *phy, int speed, int fd)
 
 
 static int marvell_read_link(struct mii_phy *phy)
 static int marvell_read_link(struct mii_phy *phy)
 {
 {
-	u16 status;
+	u16 status, pmask;
 
 
 	if (phy->autoneg) {
 	if (phy->autoneg) {
 		status = phy_read(phy, MII_M1011_PHY_SPEC_STATUS);
 		status = phy_read(phy, MII_M1011_PHY_SPEC_STATUS);
@@ -565,7 +635,9 @@ static int marvell_read_link(struct mii_phy *phy)
 			phy->duplex = DUPLEX_FULL;
 			phy->duplex = DUPLEX_FULL;
 		else
 		else
 			phy->duplex = DUPLEX_HALF;
 			phy->duplex = DUPLEX_HALF;
-		phy->pause = 0; /* XXX Check against spec ! */
+		pmask = MII_M1011_PHY_SPEC_STATUS_TX_PAUSE |
+			MII_M1011_PHY_SPEC_STATUS_RX_PAUSE;
+		phy->pause = (status & pmask) == pmask;
 	}
 	}
 	/* On non-aneg, we assume what we put in BMCR is the speed,
 	/* On non-aneg, we assume what we put in BMCR is the speed,
 	 * though magic-aneg shouldn't prevent this case from occurring
 	 * though magic-aneg shouldn't prevent this case from occurring
@@ -595,6 +667,10 @@ static int genmii_setup_aneg(struct mii_phy *phy, u32 advertise)
 		adv |= ADVERTISE_100HALF;
 		adv |= ADVERTISE_100HALF;
 	if (advertise & ADVERTISED_100baseT_Full)
 	if (advertise & ADVERTISED_100baseT_Full)
 		adv |= ADVERTISE_100FULL;
 		adv |= ADVERTISE_100FULL;
+	if (advertise & ADVERTISED_Pause)
+		adv |= ADVERTISE_PAUSE_CAP;
+	if (advertise & ADVERTISED_Asym_Pause)
+		adv |= ADVERTISE_PAUSE_ASYM;
 	phy_write(phy, MII_ADVERTISE, adv);
 	phy_write(phy, MII_ADVERTISE, adv);
 
 
 	/* Start/Restart aneg */
 	/* Start/Restart aneg */
@@ -666,7 +742,8 @@ static int genmii_read_link(struct mii_phy *phy)
 			phy->speed = SPEED_100;
 			phy->speed = SPEED_100;
 		else
 		else
 			phy->speed = SPEED_10;
 			phy->speed = SPEED_10;
-		phy->pause = 0;
+		phy->pause = (phy->duplex == DUPLEX_FULL) &&
+			((lpa & LPA_PAUSE) != 0);
 	}
 	}
 	/* On non-aneg, we assume what we put in BMCR is the speed,
 	/* On non-aneg, we assume what we put in BMCR is the speed,
 	 * though magic-aneg shouldn't prevent this case from occurring
 	 * though magic-aneg shouldn't prevent this case from occurring
@@ -676,11 +753,19 @@ static int genmii_read_link(struct mii_phy *phy)
 }
 }
 
 
 
 
-#define MII_BASIC_FEATURES	(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
-				 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
-				 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII)
-#define MII_GBIT_FEATURES	(MII_BASIC_FEATURES | \
-				 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
+#define MII_BASIC_FEATURES \
+	(SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full |	\
+	 SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full |	\
+	 SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII |	\
+	 SUPPORTED_Pause)
+
+/* On gigabit capable PHYs, we advertise Pause support but not asym pause
+ * support for now as I'm not sure it's supported and Darwin doesn't do
+ * it neither. --BenH.
+ */
+#define MII_GBIT_FEATURES \
+	(MII_BASIC_FEATURES |	\
+	 SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full)
 
 
 /* Broadcom BCM 5201 */
 /* Broadcom BCM 5201 */
 static struct mii_phy_ops bcm5201_phy_ops = {
 static struct mii_phy_ops bcm5201_phy_ops = {
@@ -720,6 +805,24 @@ static struct mii_phy_def bcm5221_phy_def = {
 	.ops		= &bcm5221_phy_ops
 	.ops		= &bcm5221_phy_ops
 };
 };
 
 
+/* Broadcom BCM 5241 */
+static struct mii_phy_ops bcm5241_phy_ops = {
+	.suspend	= bcm5241_suspend,
+	.init		= bcm5241_init,
+	.setup_aneg	= genmii_setup_aneg,
+	.setup_forced	= genmii_setup_forced,
+	.poll_link	= genmii_poll_link,
+	.read_link	= genmii_read_link,
+};
+static struct mii_phy_def bcm5241_phy_def = {
+	.phy_id		= 0x0143bc30,
+	.phy_id_mask	= 0xfffffff0,
+	.name		= "BCM5241",
+	.features	= MII_BASIC_FEATURES,
+	.magic_aneg	= 1,
+	.ops		= &bcm5241_phy_ops
+};
+
 /* Broadcom BCM 5400 */
 /* Broadcom BCM 5400 */
 static struct mii_phy_ops bcm5400_phy_ops = {
 static struct mii_phy_ops bcm5400_phy_ops = {
 	.init		= bcm5400_init,
 	.init		= bcm5400_init,
@@ -854,11 +957,8 @@ static struct mii_phy_def bcm5462V_phy_def = {
 	.ops		= &bcm5462V_phy_ops
 	.ops		= &bcm5462V_phy_ops
 };
 };
 
 
-/* Marvell 88E1101 (Apple seem to deal with 2 different revs,
- * I masked out the 8 last bits to get both, but some specs
- * would be useful here) --BenH.
- */
-static struct mii_phy_ops marvell_phy_ops = {
+/* Marvell 88E1101 amd 88E1111 */
+static struct mii_phy_ops marvell88e1101_phy_ops = {
 	.suspend	= generic_suspend,
 	.suspend	= generic_suspend,
 	.setup_aneg	= marvell_setup_aneg,
 	.setup_aneg	= marvell_setup_aneg,
 	.setup_forced	= marvell_setup_forced,
 	.setup_forced	= marvell_setup_forced,
@@ -866,13 +966,41 @@ static struct mii_phy_ops marvell_phy_ops = {
 	.read_link	= marvell_read_link
 	.read_link	= marvell_read_link
 };
 };
 
 
-static struct mii_phy_def marvell_phy_def = {
-	.phy_id		= 0x01410c00,
-	.phy_id_mask	= 0xffffff00,
-	.name		= "Marvell 88E1101",
+static struct mii_phy_ops marvell88e1111_phy_ops = {
+	.init		= marvell88e1111_init,
+	.suspend	= generic_suspend,
+	.setup_aneg	= marvell_setup_aneg,
+	.setup_forced	= marvell_setup_forced,
+	.poll_link	= genmii_poll_link,
+	.read_link	= marvell_read_link
+};
+
+/* two revs in darwin for the 88e1101 ... I could use a datasheet
+ * to get the proper names...
+ */
+static struct mii_phy_def marvell88e1101v1_phy_def = {
+	.phy_id		= 0x01410c20,
+	.phy_id_mask	= 0xfffffff0,
+	.name		= "Marvell 88E1101v1",
+	.features	= MII_GBIT_FEATURES,
+	.magic_aneg	= 1,
+	.ops		= &marvell88e1101_phy_ops
+};
+static struct mii_phy_def marvell88e1101v2_phy_def = {
+	.phy_id		= 0x01410c60,
+	.phy_id_mask	= 0xfffffff0,
+	.name		= "Marvell 88E1101v2",
+	.features	= MII_GBIT_FEATURES,
+	.magic_aneg	= 1,
+	.ops		= &marvell88e1101_phy_ops
+};
+static struct mii_phy_def marvell88e1111_phy_def = {
+	.phy_id		= 0x01410cc0,
+	.phy_id_mask	= 0xfffffff0,
+	.name		= "Marvell 88E1111",
 	.features	= MII_GBIT_FEATURES,
 	.features	= MII_GBIT_FEATURES,
 	.magic_aneg	= 1,
 	.magic_aneg	= 1,
-	.ops		= &marvell_phy_ops
+	.ops		= &marvell88e1111_phy_ops
 };
 };
 
 
 /* Generic implementation for most 10/100 PHYs */
 /* Generic implementation for most 10/100 PHYs */
@@ -895,6 +1023,7 @@ static struct mii_phy_def genmii_phy_def = {
 static struct mii_phy_def* mii_phy_table[] = {
 static struct mii_phy_def* mii_phy_table[] = {
 	&bcm5201_phy_def,
 	&bcm5201_phy_def,
 	&bcm5221_phy_def,
 	&bcm5221_phy_def,
+	&bcm5241_phy_def,
 	&bcm5400_phy_def,
 	&bcm5400_phy_def,
 	&bcm5401_phy_def,
 	&bcm5401_phy_def,
 	&bcm5411_phy_def,
 	&bcm5411_phy_def,
@@ -902,7 +1031,9 @@ static struct mii_phy_def* mii_phy_table[] = {
 	&bcm5421k2_phy_def,
 	&bcm5421k2_phy_def,
 	&bcm5461_phy_def,
 	&bcm5461_phy_def,
 	&bcm5462V_phy_def,
 	&bcm5462V_phy_def,
-	&marvell_phy_def,
+	&marvell88e1101v1_phy_def,
+	&marvell88e1101v2_phy_def,
+	&marvell88e1111_phy_def,
 	&genmii_phy_def,
 	&genmii_phy_def,
 	NULL
 	NULL
 };
 };

+ 6 - 1
drivers/net/sungem_phy.h

@@ -30,7 +30,7 @@ struct mii_phy_def
 struct mii_phy
 struct mii_phy
 {
 {
 	struct mii_phy_def*	def;
 	struct mii_phy_def*	def;
-	int			advertising;
+	u32			advertising;
 	int			mii_id;
 	int			mii_id;
 
 
 	/* 1: autoneg enabled, 0: disabled */
 	/* 1: autoneg enabled, 0: disabled */
@@ -85,6 +85,9 @@ extern int mii_phy_probe(struct mii_phy *phy, int mii_id);
 #define MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE	0x0001
 #define MII_BCM5221_SHDOW_AUX_MODE4_IDDQMODE	0x0001
 #define MII_BCM5221_SHDOW_AUX_MODE4_CLKLOPWR	0x0004
 #define MII_BCM5221_SHDOW_AUX_MODE4_CLKLOPWR	0x0004
 
 
+/* MII BCM5241 Additional registers */
+#define MII_BCM5241_SHDOW_AUX_MODE4_STANDBYPWR	0x0008
+
 /* MII BCM5400 1000-BASET Control register */
 /* MII BCM5400 1000-BASET Control register */
 #define MII_BCM5400_GB_CONTROL			0x09
 #define MII_BCM5400_GB_CONTROL			0x09
 #define MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP	0x0200
 #define MII_BCM5400_GB_CONTROL_FULLDUPLEXCAP	0x0200
@@ -115,5 +118,7 @@ extern int mii_phy_probe(struct mii_phy *phy, int mii_id);
 #define MII_M1011_PHY_SPEC_STATUS_SPD_MASK	0xc000
 #define MII_M1011_PHY_SPEC_STATUS_SPD_MASK	0xc000
 #define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX	0x2000
 #define MII_M1011_PHY_SPEC_STATUS_FULLDUPLEX	0x2000
 #define MII_M1011_PHY_SPEC_STATUS_RESOLVED	0x0800
 #define MII_M1011_PHY_SPEC_STATUS_RESOLVED	0x0800
+#define MII_M1011_PHY_SPEC_STATUS_TX_PAUSE	0x0008
+#define MII_M1011_PHY_SPEC_STATUS_RX_PAUSE	0x0004
 
 
 #endif /* __SUNGEM_PHY_H__ */
 #endif /* __SUNGEM_PHY_H__ */

+ 1 - 1
include/net/tcp.h

@@ -242,7 +242,7 @@ extern int tcp_memory_pressure;
 
 
 static inline int before(__u32 seq1, __u32 seq2)
 static inline int before(__u32 seq1, __u32 seq2)
 {
 {
-        return (__s32)(seq2-seq1) > 0;
+        return (__s32)(seq1-seq2) < 0;
 }
 }
 #define after(seq2, seq1) 	before(seq1, seq2)
 #define after(seq2, seq1) 	before(seq1, seq2)
 
 

+ 1 - 0
include/net/x25.h

@@ -259,6 +259,7 @@ extern int  x25_decode(struct sock *, struct sk_buff *, int *, int *, int *, int
 extern void x25_disconnect(struct sock *, int, unsigned char, unsigned char);
 extern void x25_disconnect(struct sock *, int, unsigned char, unsigned char);
 
 
 /* x25_timer.c */
 /* x25_timer.c */
+extern void x25_init_timers(struct sock *sk);
 extern void x25_start_heartbeat(struct sock *);
 extern void x25_start_heartbeat(struct sock *);
 extern void x25_start_t2timer(struct sock *);
 extern void x25_start_t2timer(struct sock *);
 extern void x25_start_t21timer(struct sock *);
 extern void x25_start_t21timer(struct sock *);

+ 2 - 1
net/bridge/netfilter/ebtables.c

@@ -610,7 +610,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
 	struct ebt_entry_target *t;
 	struct ebt_entry_target *t;
 	struct ebt_target *target;
 	struct ebt_target *target;
 	unsigned int i, j, hook = 0, hookmask = 0;
 	unsigned int i, j, hook = 0, hookmask = 0;
-	size_t gap = e->next_offset - e->target_offset;
+	size_t gap;
 	int ret;
 	int ret;
 
 
 	/* don't mess with the struct ebt_entries */
 	/* don't mess with the struct ebt_entries */
@@ -660,6 +660,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo,
 	if (ret != 0)
 	if (ret != 0)
 		goto cleanup_watchers;
 		goto cleanup_watchers;
 	t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
 	t = (struct ebt_entry_target *)(((char *)e) + e->target_offset);
+	gap = e->next_offset - e->target_offset;
 	target = find_target_lock(t->u.name, &ret, &ebt_mutex);
 	target = find_target_lock(t->u.name, &ret, &ebt_mutex);
 	if (!target)
 	if (!target)
 		goto cleanup_watchers;
 		goto cleanup_watchers;

+ 48 - 108
net/core/pktgen.c

@@ -148,6 +148,7 @@
 #include <linux/seq_file.h>
 #include <linux/seq_file.h>
 #include <linux/wait.h>
 #include <linux/wait.h>
 #include <linux/etherdevice.h>
 #include <linux/etherdevice.h>
+#include <linux/kthread.h>
 #include <net/checksum.h>
 #include <net/checksum.h>
 #include <net/ipv6.h>
 #include <net/ipv6.h>
 #include <net/addrconf.h>
 #include <net/addrconf.h>
@@ -360,8 +361,7 @@ struct pktgen_thread {
 	spinlock_t if_lock;
 	spinlock_t if_lock;
 	struct list_head if_list;	/* All device here */
 	struct list_head if_list;	/* All device here */
 	struct list_head th_list;
 	struct list_head th_list;
-	int removed;
-	char name[32];
+	struct task_struct *tsk;
 	char result[512];
 	char result[512];
 	u32 max_before_softirq;	/* We'll call do_softirq to prevent starvation. */
 	u32 max_before_softirq;	/* We'll call do_softirq to prevent starvation. */
 
 
@@ -1689,7 +1689,7 @@ static int pktgen_thread_show(struct seq_file *seq, void *v)
 	BUG_ON(!t);
 	BUG_ON(!t);
 
 
 	seq_printf(seq, "Name: %s  max_before_softirq: %d\n",
 	seq_printf(seq, "Name: %s  max_before_softirq: %d\n",
-		   t->name, t->max_before_softirq);
+		   t->tsk->comm, t->max_before_softirq);
 
 
 	seq_printf(seq, "Running: ");
 	seq_printf(seq, "Running: ");
 
 
@@ -3112,7 +3112,7 @@ static void pktgen_rem_thread(struct pktgen_thread *t)
 {
 {
 	/* Remove from the thread list */
 	/* Remove from the thread list */
 
 
-	remove_proc_entry(t->name, pg_proc_dir);
+	remove_proc_entry(t->tsk->comm, pg_proc_dir);
 
 
 	mutex_lock(&pktgen_thread_lock);
 	mutex_lock(&pktgen_thread_lock);
 
 
@@ -3260,58 +3260,40 @@ out:;
  * Main loop of the thread goes here
  * Main loop of the thread goes here
  */
  */
 
 
-static void pktgen_thread_worker(struct pktgen_thread *t)
+static int pktgen_thread_worker(void *arg)
 {
 {
 	DEFINE_WAIT(wait);
 	DEFINE_WAIT(wait);
+	struct pktgen_thread *t = arg;
 	struct pktgen_dev *pkt_dev = NULL;
 	struct pktgen_dev *pkt_dev = NULL;
 	int cpu = t->cpu;
 	int cpu = t->cpu;
-	sigset_t tmpsig;
 	u32 max_before_softirq;
 	u32 max_before_softirq;
 	u32 tx_since_softirq = 0;
 	u32 tx_since_softirq = 0;
 
 
-	daemonize("pktgen/%d", cpu);
-
-	/* Block all signals except SIGKILL, SIGSTOP and SIGTERM */
-
-	spin_lock_irq(&current->sighand->siglock);
-	tmpsig = current->blocked;
-	siginitsetinv(&current->blocked,
-		      sigmask(SIGKILL) | sigmask(SIGSTOP) | sigmask(SIGTERM));
-
-	recalc_sigpending();
-	spin_unlock_irq(&current->sighand->siglock);
-
-	/* Migrate to the right CPU */
-	set_cpus_allowed(current, cpumask_of_cpu(cpu));
-	if (smp_processor_id() != cpu)
-		BUG();
+	BUG_ON(smp_processor_id() != cpu);
 
 
 	init_waitqueue_head(&t->queue);
 	init_waitqueue_head(&t->queue);
 
 
-	t->control &= ~(T_TERMINATE);
-	t->control &= ~(T_RUN);
-	t->control &= ~(T_STOP);
-	t->control &= ~(T_REMDEVALL);
-	t->control &= ~(T_REMDEV);
-
 	t->pid = current->pid;
 	t->pid = current->pid;
 
 
 	PG_DEBUG(printk("pktgen: starting pktgen/%d:  pid=%d\n", cpu, current->pid));
 	PG_DEBUG(printk("pktgen: starting pktgen/%d:  pid=%d\n", cpu, current->pid));
 
 
 	max_before_softirq = t->max_before_softirq;
 	max_before_softirq = t->max_before_softirq;
 
 
-	__set_current_state(TASK_INTERRUPTIBLE);
-	mb();
+	set_current_state(TASK_INTERRUPTIBLE);
 
 
-	while (1) {
-
-		__set_current_state(TASK_RUNNING);
+	while (!kthread_should_stop()) {
+		pkt_dev = next_to_run(t);
 
 
-		/*
-		 * Get next dev to xmit -- if any.
-		 */
+		if (!pkt_dev &&
+		    (t->control & (T_STOP | T_RUN | T_REMDEVALL | T_REMDEV))
+		    == 0) {
+			prepare_to_wait(&(t->queue), &wait,
+					TASK_INTERRUPTIBLE);
+			schedule_timeout(HZ / 10);
+			finish_wait(&(t->queue), &wait);
+		}
 
 
-		pkt_dev = next_to_run(t);
+		__set_current_state(TASK_RUNNING);
 
 
 		if (pkt_dev) {
 		if (pkt_dev) {
 
 
@@ -3329,21 +3311,8 @@ static void pktgen_thread_worker(struct pktgen_thread *t)
 					do_softirq();
 					do_softirq();
 				tx_since_softirq = 0;
 				tx_since_softirq = 0;
 			}
 			}
-		} else {
-			prepare_to_wait(&(t->queue), &wait, TASK_INTERRUPTIBLE);
-			schedule_timeout(HZ / 10);
-			finish_wait(&(t->queue), &wait);
 		}
 		}
 
 
-		/*
-		 * Back from sleep, either due to the timeout or signal.
-		 * We check if we have any "posted" work for us.
-		 */
-
-		if (t->control & T_TERMINATE || signal_pending(current))
-			/* we received a request to terminate ourself */
-			break;
-
 		if (t->control & T_STOP) {
 		if (t->control & T_STOP) {
 			pktgen_stop(t);
 			pktgen_stop(t);
 			t->control &= ~(T_STOP);
 			t->control &= ~(T_STOP);
@@ -3364,20 +3333,19 @@ static void pktgen_thread_worker(struct pktgen_thread *t)
 			t->control &= ~(T_REMDEV);
 			t->control &= ~(T_REMDEV);
 		}
 		}
 
 
-		if (need_resched())
-			schedule();
+		set_current_state(TASK_INTERRUPTIBLE);
 	}
 	}
 
 
-	PG_DEBUG(printk("pktgen: %s stopping all device\n", t->name));
+	PG_DEBUG(printk("pktgen: %s stopping all device\n", t->tsk->comm));
 	pktgen_stop(t);
 	pktgen_stop(t);
 
 
-	PG_DEBUG(printk("pktgen: %s removing all device\n", t->name));
+	PG_DEBUG(printk("pktgen: %s removing all device\n", t->tsk->comm));
 	pktgen_rem_all_ifs(t);
 	pktgen_rem_all_ifs(t);
 
 
-	PG_DEBUG(printk("pktgen: %s removing thread.\n", t->name));
+	PG_DEBUG(printk("pktgen: %s removing thread.\n", t->tsk->comm));
 	pktgen_rem_thread(t);
 	pktgen_rem_thread(t);
 
 
-	t->removed = 1;
+	return 0;
 }
 }
 
 
 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
 static struct pktgen_dev *pktgen_find_dev(struct pktgen_thread *t,
@@ -3495,37 +3463,11 @@ static int pktgen_add_device(struct pktgen_thread *t, const char *ifname)
 	return add_dev_to_thread(t, pkt_dev);
 	return add_dev_to_thread(t, pkt_dev);
 }
 }
 
 
-static struct pktgen_thread *__init pktgen_find_thread(const char *name)
+static int __init pktgen_create_thread(int cpu)
 {
 {
 	struct pktgen_thread *t;
 	struct pktgen_thread *t;
-
-	mutex_lock(&pktgen_thread_lock);
-
-	list_for_each_entry(t, &pktgen_threads, th_list)
-		if (strcmp(t->name, name) == 0) {
-			mutex_unlock(&pktgen_thread_lock);
-			return t;
-		}
-
-	mutex_unlock(&pktgen_thread_lock);
-	return NULL;
-}
-
-static int __init pktgen_create_thread(const char *name, int cpu)
-{
-	int err;
-	struct pktgen_thread *t = NULL;
 	struct proc_dir_entry *pe;
 	struct proc_dir_entry *pe;
-
-	if (strlen(name) > 31) {
-		printk("pktgen: ERROR:  Thread name cannot be more than 31 characters.\n");
-		return -EINVAL;
-	}
-
-	if (pktgen_find_thread(name)) {
-		printk("pktgen: ERROR: thread: %s already exists\n", name);
-		return -EINVAL;
-	}
+	struct task_struct *p;
 
 
 	t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL);
 	t = kzalloc(sizeof(struct pktgen_thread), GFP_KERNEL);
 	if (!t) {
 	if (!t) {
@@ -3533,14 +3475,29 @@ static int __init pktgen_create_thread(const char *name, int cpu)
 		return -ENOMEM;
 		return -ENOMEM;
 	}
 	}
 
 
-	strcpy(t->name, name);
 	spin_lock_init(&t->if_lock);
 	spin_lock_init(&t->if_lock);
 	t->cpu = cpu;
 	t->cpu = cpu;
 
 
-	pe = create_proc_entry(t->name, 0600, pg_proc_dir);
+	INIT_LIST_HEAD(&t->if_list);
+
+	list_add_tail(&t->th_list, &pktgen_threads);
+
+	p = kthread_create(pktgen_thread_worker, t, "kpktgend_%d", cpu);
+	if (IS_ERR(p)) {
+		printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu);
+		list_del(&t->th_list);
+		kfree(t);
+		return PTR_ERR(p);
+	}
+	kthread_bind(p, cpu);
+	t->tsk = p;
+
+	pe = create_proc_entry(t->tsk->comm, 0600, pg_proc_dir);
 	if (!pe) {
 	if (!pe) {
 		printk("pktgen: cannot create %s/%s procfs entry.\n",
 		printk("pktgen: cannot create %s/%s procfs entry.\n",
-		       PG_PROC_DIR, t->name);
+		       PG_PROC_DIR, t->tsk->comm);
+		kthread_stop(p);
+		list_del(&t->th_list);
 		kfree(t);
 		kfree(t);
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
@@ -3548,21 +3505,7 @@ static int __init pktgen_create_thread(const char *name, int cpu)
 	pe->proc_fops = &pktgen_thread_fops;
 	pe->proc_fops = &pktgen_thread_fops;
 	pe->data = t;
 	pe->data = t;
 
 
-	INIT_LIST_HEAD(&t->if_list);
-
-	list_add_tail(&t->th_list, &pktgen_threads);
-
-	t->removed = 0;
-
-	err = kernel_thread((void *)pktgen_thread_worker, (void *)t,
-			  CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
-	if (err < 0) {
-		printk("pktgen: kernel_thread() failed for cpu %d\n", t->cpu);
-		remove_proc_entry(t->name, pg_proc_dir);
-		list_del(&t->th_list);
-		kfree(t);
-		return err;
-	}
+	wake_up_process(p);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -3643,10 +3586,8 @@ static int __init pg_init(void)
 
 
 	for_each_online_cpu(cpu) {
 	for_each_online_cpu(cpu) {
 		int err;
 		int err;
-		char buf[30];
 
 
-		sprintf(buf, "kpktgend_%i", cpu);
-		err = pktgen_create_thread(buf, cpu);
+		err = pktgen_create_thread(cpu);
 		if (err)
 		if (err)
 			printk("pktgen: WARNING: Cannot create thread for cpu %d (%d)\n",
 			printk("pktgen: WARNING: Cannot create thread for cpu %d (%d)\n",
 					cpu, err);
 					cpu, err);
@@ -3674,9 +3615,8 @@ static void __exit pg_cleanup(void)
 
 
 	list_for_each_safe(q, n, &pktgen_threads) {
 	list_for_each_safe(q, n, &pktgen_threads) {
 		t = list_entry(q, struct pktgen_thread, th_list);
 		t = list_entry(q, struct pktgen_thread, th_list);
-		t->control |= (T_TERMINATE);
-
-		wait_event_interruptible_timeout(queue, (t->removed == 1), HZ);
+		kthread_stop(t->tsk);
+		kfree(t);
 	}
 	}
 
 
 	/* Un-register us from receiving netdevice events */
 	/* Un-register us from receiving netdevice events */

+ 3 - 2
net/ipv4/devinet.c

@@ -165,9 +165,8 @@ struct in_device *inetdev_init(struct net_device *dev)
 			      NET_IPV4_NEIGH, "ipv4", NULL, NULL);
 			      NET_IPV4_NEIGH, "ipv4", NULL, NULL);
 #endif
 #endif
 
 
-	/* Account for reference dev->ip_ptr */
+	/* Account for reference dev->ip_ptr (below) */
 	in_dev_hold(in_dev);
 	in_dev_hold(in_dev);
-	rcu_assign_pointer(dev->ip_ptr, in_dev);
 
 
 #ifdef CONFIG_SYSCTL
 #ifdef CONFIG_SYSCTL
 	devinet_sysctl_register(in_dev, &in_dev->cnf);
 	devinet_sysctl_register(in_dev, &in_dev->cnf);
@@ -176,6 +175,8 @@ struct in_device *inetdev_init(struct net_device *dev)
 	if (dev->flags & IFF_UP)
 	if (dev->flags & IFF_UP)
 		ip_mc_up(in_dev);
 		ip_mc_up(in_dev);
 out:
 out:
+	/* we can receive as soon as ip_ptr is set -- do this last */
+	rcu_assign_pointer(dev->ip_ptr, in_dev);
 	return in_dev;
 	return in_dev;
 out_kfree:
 out_kfree:
 	kfree(in_dev);
 	kfree(in_dev);

+ 5 - 2
net/ipv4/netfilter.c

@@ -15,16 +15,19 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type)
 	struct flowi fl = {};
 	struct flowi fl = {};
 	struct dst_entry *odst;
 	struct dst_entry *odst;
 	unsigned int hh_len;
 	unsigned int hh_len;
+	unsigned int type;
 
 
+	type = inet_addr_type(iph->saddr);
 	if (addr_type == RTN_UNSPEC)
 	if (addr_type == RTN_UNSPEC)
-		addr_type = inet_addr_type(iph->saddr);
+		addr_type = type;
 
 
 	/* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
 	/* some non-standard hacks like ipt_REJECT.c:send_reset() can cause
 	 * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
 	 * packets with foreign saddr to appear on the NF_IP_LOCAL_OUT hook.
 	 */
 	 */
 	if (addr_type == RTN_LOCAL) {
 	if (addr_type == RTN_LOCAL) {
 		fl.nl_u.ip4_u.daddr = iph->daddr;
 		fl.nl_u.ip4_u.daddr = iph->daddr;
-		fl.nl_u.ip4_u.saddr = iph->saddr;
+		if (type == RTN_LOCAL)
+			fl.nl_u.ip4_u.saddr = iph->saddr;
 		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
 		fl.nl_u.ip4_u.tos = RT_TOS(iph->tos);
 		fl.oif = (*pskb)->sk ? (*pskb)->sk->sk_bound_dev_if : 0;
 		fl.oif = (*pskb)->sk ? (*pskb)->sk->sk_bound_dev_if : 0;
 		fl.mark = (*pskb)->mark;
 		fl.mark = (*pskb)->mark;

+ 2 - 2
net/ipv4/netfilter/Kconfig

@@ -6,8 +6,8 @@ menu "IP: Netfilter Configuration"
 	depends on INET && NETFILTER
 	depends on INET && NETFILTER
 
 
 config NF_CONNTRACK_IPV4
 config NF_CONNTRACK_IPV4
-	tristate "IPv4 connection tracking support (required for NAT) (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	tristate "IPv4 connection tracking support (required for NAT)"
+	depends on NF_CONNTRACK
 	---help---
 	---help---
 	  Connection tracking keeps a record of what packets have passed
 	  Connection tracking keeps a record of what packets have passed
 	  through your machine, in order to figure out how they are related
 	  through your machine, in order to figure out how they are related

+ 5 - 5
net/ipv4/netfilter/ip_tables.c

@@ -919,13 +919,13 @@ copy_entries_to_user(unsigned int total_size,
 #ifdef CONFIG_COMPAT
 #ifdef CONFIG_COMPAT
 struct compat_delta {
 struct compat_delta {
 	struct compat_delta *next;
 	struct compat_delta *next;
-	u_int16_t offset;
+	unsigned int offset;
 	short delta;
 	short delta;
 };
 };
 
 
 static struct compat_delta *compat_offsets = NULL;
 static struct compat_delta *compat_offsets = NULL;
 
 
-static int compat_add_offset(u_int16_t offset, short delta)
+static int compat_add_offset(unsigned int offset, short delta)
 {
 {
 	struct compat_delta *tmp;
 	struct compat_delta *tmp;
 
 
@@ -957,7 +957,7 @@ static void compat_flush_offsets(void)
 	}
 	}
 }
 }
 
 
-static short compat_calc_jump(u_int16_t offset)
+static short compat_calc_jump(unsigned int offset)
 {
 {
 	struct compat_delta *tmp;
 	struct compat_delta *tmp;
 	short delta;
 	short delta;
@@ -997,7 +997,7 @@ static int compat_calc_entry(struct ipt_entry *e, struct xt_table_info *info,
 		void *base, struct xt_table_info *newinfo)
 		void *base, struct xt_table_info *newinfo)
 {
 {
 	struct ipt_entry_target *t;
 	struct ipt_entry_target *t;
-	u_int16_t entry_offset;
+	unsigned int entry_offset;
 	int off, i, ret;
 	int off, i, ret;
 
 
 	off = 0;
 	off = 0;
@@ -1467,7 +1467,7 @@ check_compat_entry_size_and_hooks(struct ipt_entry *e,
 {
 {
 	struct ipt_entry_target *t;
 	struct ipt_entry_target *t;
 	struct ipt_target *target;
 	struct ipt_target *target;
-	u_int16_t entry_offset;
+	unsigned int entry_offset;
 	int ret, off, h, j;
 	int ret, off, h, j;
 
 
 	duprintf("check_compat_entry_size_and_hooks %p\n", e);
 	duprintf("check_compat_entry_size_and_hooks %p\n", e);

+ 4 - 1
net/ipv4/netfilter/ipt_MASQUERADE.c

@@ -127,10 +127,13 @@ masquerade_target(struct sk_buff **pskb,
 static inline int
 static inline int
 device_cmp(struct ip_conntrack *i, void *ifindex)
 device_cmp(struct ip_conntrack *i, void *ifindex)
 {
 {
+	int ret;
 #ifdef CONFIG_NF_NAT_NEEDED
 #ifdef CONFIG_NF_NAT_NEEDED
 	struct nf_conn_nat *nat = nfct_nat(i);
 	struct nf_conn_nat *nat = nfct_nat(i);
+
+	if (!nat)
+		return 0;
 #endif
 #endif
-	int ret;
 
 
 	read_lock_bh(&masq_lock);
 	read_lock_bh(&masq_lock);
 #ifdef CONFIG_NF_NAT_NEEDED
 #ifdef CONFIG_NF_NAT_NEEDED

+ 2 - 2
net/ipv6/addrconf.c

@@ -413,8 +413,6 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
 	if (netif_carrier_ok(dev))
 	if (netif_carrier_ok(dev))
 		ndev->if_flags |= IF_READY;
 		ndev->if_flags |= IF_READY;
 
 
-	/* protected by rtnl_lock */
-	rcu_assign_pointer(dev->ip6_ptr, ndev);
 
 
 	ipv6_mc_init_dev(ndev);
 	ipv6_mc_init_dev(ndev);
 	ndev->tstamp = jiffies;
 	ndev->tstamp = jiffies;
@@ -425,6 +423,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
 			      NULL);
 			      NULL);
 	addrconf_sysctl_register(ndev, &ndev->cnf);
 	addrconf_sysctl_register(ndev, &ndev->cnf);
 #endif
 #endif
+	/* protected by rtnl_lock */
+	rcu_assign_pointer(dev->ip6_ptr, ndev);
 	return ndev;
 	return ndev;
 }
 }
 
 

+ 12 - 13
net/netfilter/Kconfig

@@ -44,8 +44,7 @@ choice
 	depends on NF_CONNTRACK_ENABLED
 	depends on NF_CONNTRACK_ENABLED
 
 
 config NF_CONNTRACK_SUPPORT
 config NF_CONNTRACK_SUPPORT
-	bool "Layer 3 Independent Connection tracking (EXPERIMENTAL)"
-	depends on EXPERIMENTAL
+	bool "Layer 3 Independent Connection tracking"
 	help
 	help
 	  Layer 3 independent connection tracking is experimental scheme
 	  Layer 3 independent connection tracking is experimental scheme
 	  which generalize ip_conntrack to support other layer 3 protocols.
 	  which generalize ip_conntrack to support other layer 3 protocols.
@@ -122,7 +121,7 @@ config NF_CONNTRACK_EVENTS
 
 
 config NF_CT_PROTO_GRE
 config NF_CT_PROTO_GRE
 	tristate
 	tristate
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	depends on NF_CONNTRACK
 
 
 config NF_CT_PROTO_SCTP
 config NF_CT_PROTO_SCTP
 	tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
 	tristate 'SCTP protocol connection tracking support (EXPERIMENTAL)'
@@ -136,8 +135,8 @@ config NF_CT_PROTO_SCTP
 	  Documentation/modules.txt.  If unsure, say `N'.
 	  Documentation/modules.txt.  If unsure, say `N'.
 
 
 config NF_CONNTRACK_AMANDA
 config NF_CONNTRACK_AMANDA
-	tristate "Amanda backup protocol support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	tristate "Amanda backup protocol support"
+	depends on NF_CONNTRACK
 	select TEXTSEARCH
 	select TEXTSEARCH
 	select TEXTSEARCH_KMP
 	select TEXTSEARCH_KMP
 	help
 	help
@@ -151,8 +150,8 @@ config NF_CONNTRACK_AMANDA
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
 config NF_CONNTRACK_FTP
 config NF_CONNTRACK_FTP
-	tristate "FTP protocol support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	tristate "FTP protocol support"
+	depends on NF_CONNTRACK
 	help
 	help
 	  Tracking FTP connections is problematic: special helpers are
 	  Tracking FTP connections is problematic: special helpers are
 	  required for tracking them, and doing masquerading and other forms
 	  required for tracking them, and doing masquerading and other forms
@@ -184,8 +183,8 @@ config NF_CONNTRACK_H323
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
 config NF_CONNTRACK_IRC
 config NF_CONNTRACK_IRC
-	tristate "IRC protocol support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	tristate "IRC protocol support"
+	depends on NF_CONNTRACK
 	help
 	help
 	  There is a commonly-used extension to IRC called
 	  There is a commonly-used extension to IRC called
 	  Direct Client-to-Client Protocol (DCC).  This enables users to send
 	  Direct Client-to-Client Protocol (DCC).  This enables users to send
@@ -218,8 +217,8 @@ config NF_CONNTRACK_NETBIOS_NS
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
 config NF_CONNTRACK_PPTP
 config NF_CONNTRACK_PPTP
-	tristate "PPtP protocol support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	tristate "PPtP protocol support"
+	depends on NF_CONNTRACK
 	select NF_CT_PROTO_GRE
 	select NF_CT_PROTO_GRE
 	help
 	help
 	  This module adds support for PPTP (Point to Point Tunnelling
 	  This module adds support for PPTP (Point to Point Tunnelling
@@ -249,8 +248,8 @@ config NF_CONNTRACK_SIP
 	  To compile it as a module, choose M here.  If unsure, say N.
 	  To compile it as a module, choose M here.  If unsure, say N.
 
 
 config NF_CONNTRACK_TFTP
 config NF_CONNTRACK_TFTP
-	tristate "TFTP protocol support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && NF_CONNTRACK
+	tristate "TFTP protocol support"
+	depends on NF_CONNTRACK
 	help
 	help
 	  TFTP connection tracking helper, this is required depending
 	  TFTP connection tracking helper, this is required depending
 	  on how restrictive your ruleset is.
 	  on how restrictive your ruleset is.

+ 1 - 1
net/netfilter/xt_hashlimit.c

@@ -745,7 +745,7 @@ static int __init xt_hashlimit_init(void)
 	}
 	}
 	hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", proc_net);
 	hashlimit_procdir6 = proc_mkdir("ip6t_hashlimit", proc_net);
 	if (!hashlimit_procdir6) {
 	if (!hashlimit_procdir6) {
-		printk(KERN_ERR "xt_hashlimit: tnable to create proc dir "
+		printk(KERN_ERR "xt_hashlimit: unable to create proc dir "
 				"entry\n");
 				"entry\n");
 		goto err4;
 		goto err4;
 	}
 	}

+ 1 - 2
net/netlink/af_netlink.c

@@ -472,8 +472,7 @@ static int netlink_release(struct socket *sock)
 				NETLINK_URELEASE, &n);
 				NETLINK_URELEASE, &n);
 	}	
 	}	
 
 
-	if (nlk->module)
-		module_put(nlk->module);
+	module_put(nlk->module);
 
 
 	netlink_table_grab();
 	netlink_table_grab();
 	if (nlk->flags & NETLINK_KERNEL_SOCKET) {
 	if (nlk->flags & NETLINK_KERNEL_SOCKET) {

+ 0 - 2
net/x25/af_x25.c

@@ -484,8 +484,6 @@ out:
 	return sk;
 	return sk;
 }
 }
 
 
-void x25_init_timers(struct sock *sk);
-
 static int x25_create(struct socket *sock, int protocol)
 static int x25_create(struct socket *sock, int protocol)
 {
 {
 	struct sock *sk;
 	struct sock *sk;

+ 42 - 31
net/xfrm/xfrm_user.c

@@ -434,18 +434,19 @@ error_no_put:
 	return NULL;
 	return NULL;
 }
 }
 
 
-static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_add_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_usersa_info *p = NLMSG_DATA(nlh);
 	struct xfrm_usersa_info *p = NLMSG_DATA(nlh);
 	struct xfrm_state *x;
 	struct xfrm_state *x;
 	int err;
 	int err;
 	struct km_event c;
 	struct km_event c;
 
 
-	err = verify_newsa_info(p, (struct rtattr **)xfrma);
+	err = verify_newsa_info(p, xfrma);
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
-	x = xfrm_state_construct(p, (struct rtattr **)xfrma, &err);
+	x = xfrm_state_construct(p, xfrma, &err);
 	if (!x)
 	if (!x)
 		return err;
 		return err;
 
 
@@ -507,14 +508,15 @@ static struct xfrm_state *xfrm_user_state_lookup(struct xfrm_usersa_id *p,
 	return x;
 	return x;
 }
 }
 
 
-static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_del_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_state *x;
 	struct xfrm_state *x;
 	int err = -ESRCH;
 	int err = -ESRCH;
 	struct km_event c;
 	struct km_event c;
 	struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
 	struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
 
 
-	x = xfrm_user_state_lookup(p, (struct rtattr **)xfrma, &err);
+	x = xfrm_user_state_lookup(p, xfrma, &err);
 	if (x == NULL)
 	if (x == NULL)
 		return err;
 		return err;
 
 
@@ -672,14 +674,15 @@ static struct sk_buff *xfrm_state_netlink(struct sk_buff *in_skb,
 	return skb;
 	return skb;
 }
 }
 
 
-static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_get_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
 	struct xfrm_usersa_id *p = NLMSG_DATA(nlh);
 	struct xfrm_state *x;
 	struct xfrm_state *x;
 	struct sk_buff *resp_skb;
 	struct sk_buff *resp_skb;
 	int err = -ESRCH;
 	int err = -ESRCH;
 
 
-	x = xfrm_user_state_lookup(p, (struct rtattr **)xfrma, &err);
+	x = xfrm_user_state_lookup(p, xfrma, &err);
 	if (x == NULL)
 	if (x == NULL)
 		goto out_noput;
 		goto out_noput;
 
 
@@ -718,7 +721,8 @@ static int verify_userspi_info(struct xfrm_userspi_info *p)
 	return 0;
 	return 0;
 }
 }
 
 
-static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_state *x;
 	struct xfrm_state *x;
 	struct xfrm_userspi_info *p;
 	struct xfrm_userspi_info *p;
@@ -1013,7 +1017,8 @@ static struct xfrm_policy *xfrm_policy_construct(struct xfrm_userpolicy_info *p,
 	return NULL;
 	return NULL;
 }
 }
 
 
-static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_userpolicy_info *p = NLMSG_DATA(nlh);
 	struct xfrm_userpolicy_info *p = NLMSG_DATA(nlh);
 	struct xfrm_policy *xp;
 	struct xfrm_policy *xp;
@@ -1024,11 +1029,11 @@ static int xfrm_add_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
 	err = verify_newpolicy_info(p);
 	err = verify_newpolicy_info(p);
 	if (err)
 	if (err)
 		return err;
 		return err;
-	err = verify_sec_ctx_len((struct rtattr **)xfrma);
+	err = verify_sec_ctx_len(xfrma);
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
-	xp = xfrm_policy_construct(p, (struct rtattr **)xfrma, &err);
+	xp = xfrm_policy_construct(p, xfrma, &err);
 	if (!xp)
 	if (!xp)
 		return err;
 		return err;
 
 
@@ -1227,7 +1232,8 @@ static struct sk_buff *xfrm_policy_netlink(struct sk_buff *in_skb,
 	return skb;
 	return skb;
 }
 }
 
 
-static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_policy *xp;
 	struct xfrm_policy *xp;
 	struct xfrm_userpolicy_id *p;
 	struct xfrm_userpolicy_id *p;
@@ -1239,7 +1245,7 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
 	p = NLMSG_DATA(nlh);
 	p = NLMSG_DATA(nlh);
 	delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
 	delete = nlh->nlmsg_type == XFRM_MSG_DELPOLICY;
 
 
-	err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
+	err = copy_from_user_policy_type(&type, xfrma);
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
@@ -1250,11 +1256,10 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
 	if (p->index)
 	if (p->index)
 		xp = xfrm_policy_byid(type, p->dir, p->index, delete);
 		xp = xfrm_policy_byid(type, p->dir, p->index, delete);
 	else {
 	else {
-		struct rtattr **rtattrs = (struct rtattr **)xfrma;
-		struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
+		struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
 		struct xfrm_policy tmp;
 		struct xfrm_policy tmp;
 
 
-		err = verify_sec_ctx_len(rtattrs);
+		err = verify_sec_ctx_len(xfrma);
 		if (err)
 		if (err)
 			return err;
 			return err;
 
 
@@ -1302,7 +1307,8 @@ out:
 	return err;
 	return err;
 }
 }
 
 
-static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_flush_sa(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct km_event c;
 	struct km_event c;
 	struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
 	struct xfrm_usersa_flush *p = NLMSG_DATA(nlh);
@@ -1367,7 +1373,8 @@ nlmsg_failure:
 	return -1;
 	return -1;
 }
 }
 
 
-static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_state *x;
 	struct xfrm_state *x;
 	struct sk_buff *r_skb;
 	struct sk_buff *r_skb;
@@ -1415,7 +1422,8 @@ static int xfrm_get_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
 	return err;
 	return err;
 }
 }
 
 
-static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_state *x;
 	struct xfrm_state *x;
 	struct km_event c;
 	struct km_event c;
@@ -1439,7 +1447,7 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
 		goto out;
 		goto out;
 
 
 	spin_lock_bh(&x->lock);
 	spin_lock_bh(&x->lock);
-	err = xfrm_update_ae_params(x,(struct rtattr **)xfrma);
+	err = xfrm_update_ae_params(x, xfrma);
 	spin_unlock_bh(&x->lock);
 	spin_unlock_bh(&x->lock);
 	if (err	< 0)
 	if (err	< 0)
 		goto out;
 		goto out;
@@ -1455,14 +1463,15 @@ out:
 	return err;
 	return err;
 }
 }
 
 
-static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct km_event c;
 	struct km_event c;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	int err;
 	int err;
 	struct xfrm_audit audit_info;
 	struct xfrm_audit audit_info;
 
 
-	err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
+	err = copy_from_user_policy_type(&type, xfrma);
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
@@ -1477,7 +1486,8 @@ static int xfrm_flush_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **x
 	return 0;
 	return 0;
 }
 }
 
 
-static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_policy *xp;
 	struct xfrm_policy *xp;
 	struct xfrm_user_polexpire *up = NLMSG_DATA(nlh);
 	struct xfrm_user_polexpire *up = NLMSG_DATA(nlh);
@@ -1485,18 +1495,17 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void *
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	u8 type = XFRM_POLICY_TYPE_MAIN;
 	int err = -ENOENT;
 	int err = -ENOENT;
 
 
-	err = copy_from_user_policy_type(&type, (struct rtattr **)xfrma);
+	err = copy_from_user_policy_type(&type, xfrma);
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
 	if (p->index)
 	if (p->index)
 		xp = xfrm_policy_byid(type, p->dir, p->index, 0);
 		xp = xfrm_policy_byid(type, p->dir, p->index, 0);
 	else {
 	else {
-		struct rtattr **rtattrs = (struct rtattr **)xfrma;
-		struct rtattr *rt = rtattrs[XFRMA_SEC_CTX-1];
+		struct rtattr *rt = xfrma[XFRMA_SEC_CTX-1];
 		struct xfrm_policy tmp;
 		struct xfrm_policy tmp;
 
 
-		err = verify_sec_ctx_len(rtattrs);
+		err = verify_sec_ctx_len(xfrma);
 		if (err)
 		if (err)
 			return err;
 			return err;
 
 
@@ -1537,7 +1546,8 @@ out:
 	return err;
 	return err;
 }
 }
 
 
-static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_state *x;
 	struct xfrm_state *x;
 	int err;
 	int err;
@@ -1568,7 +1578,8 @@ out:
 	return err;
 	return err;
 }
 }
 
 
-static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
+static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh,
+		struct rtattr **xfrma)
 {
 {
 	struct xfrm_policy *xp;
 	struct xfrm_policy *xp;
 	struct xfrm_user_tmpl *ut;
 	struct xfrm_user_tmpl *ut;
@@ -1647,7 +1658,7 @@ static const int xfrm_msg_min[XFRM_NR_MSGTYPES] = {
 #undef XMSGSIZE
 #undef XMSGSIZE
 
 
 static struct xfrm_link {
 static struct xfrm_link {
-	int (*doit)(struct sk_buff *, struct nlmsghdr *, void **);
+	int (*doit)(struct sk_buff *, struct nlmsghdr *, struct rtattr **);
 	int (*dump)(struct sk_buff *, struct netlink_callback *);
 	int (*dump)(struct sk_buff *, struct netlink_callback *);
 } xfrm_dispatch[XFRM_NR_MSGTYPES] = {
 } xfrm_dispatch[XFRM_NR_MSGTYPES] = {
 	[XFRM_MSG_NEWSA       - XFRM_MSG_BASE] = { .doit = xfrm_add_sa        },
 	[XFRM_MSG_NEWSA       - XFRM_MSG_BASE] = { .doit = xfrm_add_sa        },
@@ -1735,7 +1746,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err
 
 
 	if (link->doit == NULL)
 	if (link->doit == NULL)
 		goto err_einval;
 		goto err_einval;
-	*errp = link->doit(skb, nlh, (void **) &xfrma);
+	*errp = link->doit(skb, nlh, xfrma);
 
 
 	return *errp;
 	return *errp;