Commit 8be7ed14 authored by Linus Torvalds's avatar Linus Torvalds

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
parents d1398a6f 30c4cf57
...@@ -349,22 +349,11 @@ static void __init trif_probe2(int unit) ...@@ -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);
......
...@@ -154,8 +154,8 @@ static int ifb_xmit(struct sk_buff *skb, struct net_device *dev) ...@@ -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->rx_packets++;
stats->tx_bytes+=skb->len; stats->rx_bytes+=skb->len;
if (!from || !skb->input_dev) { if (!from || !skb->input_dev) {
dropped: dropped:
......
...@@ -229,9 +229,11 @@ struct net_device loopback_dev = { ...@@ -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);
...@@ -90,7 +90,8 @@ ...@@ -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"
......
...@@ -3,10 +3,9 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -676,11 +753,19 @@ static int genmii_read_link(struct mii_phy *phy)
} }
#define MII_BASIC_FEATURES (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \ #define MII_BASIC_FEATURES \
SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \ (SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full | \
SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII) SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
#define MII_GBIT_FEATURES (MII_BASIC_FEATURES | \ SUPPORTED_Autoneg | SUPPORTED_TP | SUPPORTED_MII | \
SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full) 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 = { ...@@ -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 = { ...@@ -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, /* Marvell 88E1101 amd 88E1111 */
* I masked out the 8 last bits to get both, but some specs static struct mii_phy_ops marvell88e1101_phy_ops = {
* would be useful here) --BenH.
*/
static struct mii_phy_ops marvell_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 = { ...@@ -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 = { static struct mii_phy_ops marvell88e1111_phy_ops = {
.phy_id = 0x01410c00, .init = marvell88e1111_init,
.phy_id_mask = 0xffffff00, .suspend = generic_suspend,
.name = "Marvell 88E1101", .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 = { ...@@ -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[] = { ...@@ -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
}; };
......
...@@ -30,7 +30,7 @@ struct mii_phy_def ...@@ -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); ...@@ -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); ...@@ -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__ */
...@@ -242,7 +242,7 @@ extern int tcp_memory_pressure; ...@@ -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)
......
...@@ -259,6 +259,7 @@ extern int x25_decode(struct sock *, struct sk_buff *, int *, int *, int *, int ...@@ -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 *);
......
...@@ -610,7 +610,7 @@ ebt_check_entry(struct ebt_entry *e, struct ebt_table_info *newinfo, ...@@ -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, ...@@ -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;
......
...@@ -148,6 +148,7 @@ ...@@ -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 { ...@@ -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; struct task_struct *tsk;
char name[32];
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) ...@@ -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) ...@@ -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:; ...@@ -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); BUG_ON(smp_processor_id() != 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();
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); set_current_state(TASK_INTERRUPTIBLE);
mb();
while (1) { while (!kthread_should_stop()) {
pkt_dev = next_to_run(t);
__set_current_state(TASK_RUNNING);
/* if (!pkt_dev &&
* Get next dev to xmit -- if any. (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) ...@@ -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) ...@@ -3364,20 +3333,19 @@ static void pktgen_thread_worker(struct pktgen_thread *t)
t->control &= ~(T_REMDEV); t->control &= ~(T_REMDEV);
} }
if (need_resched()) set_current_state(TASK_INTERRUPTIBLE);
schedule();
} }
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) ...@@ -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;
struct task_struct *p;
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;
}
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) ...@@ -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) ...@@ -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); wake_up_process(p);
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;
}
return 0; return 0;
} }
...@@ -3643,10 +3586,8 @@ static int __init pg_init(void) ...@@ -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(cpu);
err = pktgen_create_thread(buf, 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) ...@@ -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); kthread_stop(t->tsk);
kfree(t);
wait_event_interruptible_timeout(queue, (t->removed == 1), HZ);
} }
/* Un-register us from receiving netdevice events */ /* Un-register us from receiving netdevice events */
......
...@@ -165,9 +165,8 @@ struct in_device *inetdev_init(struct net_device *dev) ...@@ -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) ...@@ -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);
......
...@@ -15,16 +15,19 @@ int ip_route_me_harder(struct sk_buff **pskb, unsigned addr_type) ...@@ -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;
......
...@@ -6,8 +6,8 @@ menu "IP: Netfilter Configuration" ...@@ -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)" tristate "IPv4 connection tracking support (required for NAT)"
depends on EXPERIMENTAL && NF_CONNTRACK 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
......
...@@ -919,13 +919,13 @@ copy_entries_to_user(unsigned int total_size, ...@@ -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) ...@@ -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, ...@@ -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, ...@@ -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);
......
...@@ -127,10 +127,13 @@ masquerade_target(struct sk_buff **pskb, ...@@ -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
......
...@@ -413,8 +413,6 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) ...@@ -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) ...@@ -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;
} }
......
...@@ -44,8 +44,7 @@ choice ...@@ -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)" bool "Layer 3 Independent Connection tracking"
depends on EXPERIMENTAL
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 ...@@ -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 ...@@ -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)" tristate "Amanda backup protocol support"
depends on EXPERIMENTAL && NF_CONNTRACK depends on NF_CONNTRACK
select TEXTSEARCH select TEXTSEARCH
select TEXTSEARCH_KMP select TEXTSEARCH_KMP
help help
...@@ -151,8 +150,8 @@ config NF_CONNTRACK_AMANDA ...@@ -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)" tristate "FTP protocol support"
depends on EXPERIMENTAL && NF_CONNTRACK 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 ...@@ -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)" tristate "IRC protocol support"
depends on EXPERIMENTAL && NF_CONNTRACK 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 ...@@ -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)" tristate "PPtP protocol support"
depends on EXPERIMENTAL && NF_CONNTRACK 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 ...@@ -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)" tristate "TFTP protocol support"
depends on EXPERIMENTAL && NF_CONNTRACK 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.
......
...@@ -745,7 +745,7 @@ static int __init xt_hashlimit_init(void) ...@@ -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;
} }
......
...@@ -472,8 +472,7 @@ static int netlink_release(struct socket *sock) ...@@ -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) {
......
...@@ -484,8 +484,6 @@ static struct sock *x25_alloc_socket(void) ...@@ -484,8 +484,6 @@ static struct sock *x25_alloc_socket(void)
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;
......
...@@ -434,18 +434,19 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p, ...@@ -434,18 +434,19 @@ static struct xfrm_state *xfrm_state_construct(struct xfrm_usersa_info *p,
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, ...@@ -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, ...@@ -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) ...@@ -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, ...@@ -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 ...@@ -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, ...@@ -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 ...@@ -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 ...@@ -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 = xfrma[XFRMA_SEC_CTX-1];
struct rtattr *rt = rtattrs[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 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr ...@@ -1302,7 +1307,8 @@ static int xfrm_get_policy(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfr
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 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve ...@@ -1367,7 +1373,8 @@ static int build_aevent(struct sk_buff *skb, struct xfrm_state *x, struct km_eve
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) ...@@ -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) ...@@ -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 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma) ...@@ -1455,14 +1463,15 @@ static int xfrm_new_ae(struct sk_buff *skb, struct nlmsghdr *nlh, void **xfrma)
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 ...@@ -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 * ...@@ -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 = xfrma[XFRMA_SEC_CTX-1];
struct rtattr *rt = rtattrs[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 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void * ...@@ -1537,7 +1546,8 @@ static int xfrm_add_pol_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void *
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 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void ** ...@@ -1568,7 +1578,8 @@ static int xfrm_add_sa_expire(struct sk_buff *skb, struct nlmsghdr *nlh, void **
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] = { ...@@ -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 ...@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment