Commit 51df1901 authored by Simon Horman's avatar Simon Horman
parents 4a031b0e 23197916
...@@ -66,8 +66,8 @@ ...@@ -66,8 +66,8 @@
#define DRV_MODULE_NAME "tg3" #define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "3.93" #define DRV_MODULE_VERSION "3.94"
#define DRV_MODULE_RELDATE "May 22, 2008" #define DRV_MODULE_RELDATE "August 14, 2008"
#define TG3_DEF_MAC_MODE 0 #define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0 #define TG3_DEF_RX_MODE 0
...@@ -536,6 +536,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum) ...@@ -536,6 +536,7 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
return 0; return 0;
switch (locknum) { switch (locknum) {
case TG3_APE_LOCK_GRC:
case TG3_APE_LOCK_MEM: case TG3_APE_LOCK_MEM:
break; break;
default: default:
...@@ -573,6 +574,7 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum) ...@@ -573,6 +574,7 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
return; return;
switch (locknum) { switch (locknum) {
case TG3_APE_LOCK_GRC:
case TG3_APE_LOCK_MEM: case TG3_APE_LOCK_MEM:
break; break;
default: default:
...@@ -1017,16 +1019,44 @@ static void tg3_mdio_fini(struct tg3 *tp) ...@@ -1017,16 +1019,44 @@ static void tg3_mdio_fini(struct tg3 *tp)
} }
} }
/* tp->lock is held. */
static inline void tg3_generate_fw_event(struct tg3 *tp)
{
u32 val;
val = tr32(GRC_RX_CPU_EVENT);
val |= GRC_RX_CPU_DRIVER_EVENT;
tw32_f(GRC_RX_CPU_EVENT, val);
tp->last_event_jiffies = jiffies;
}
#define TG3_FW_EVENT_TIMEOUT_USEC 2500
/* tp->lock is held. */ /* tp->lock is held. */
static void tg3_wait_for_event_ack(struct tg3 *tp) static void tg3_wait_for_event_ack(struct tg3 *tp)
{ {
int i; int i;
unsigned int delay_cnt;
long time_remain;
/* If enough time has passed, no wait is necessary. */
time_remain = (long)(tp->last_event_jiffies + 1 +
usecs_to_jiffies(TG3_FW_EVENT_TIMEOUT_USEC)) -
(long)jiffies;
if (time_remain < 0)
return;
/* Wait for up to 2.5 milliseconds */ /* Check if we can shorten the wait time. */
for (i = 0; i < 250000; i++) { delay_cnt = jiffies_to_usecs(time_remain);
if (delay_cnt > TG3_FW_EVENT_TIMEOUT_USEC)
delay_cnt = TG3_FW_EVENT_TIMEOUT_USEC;
delay_cnt = (delay_cnt >> 3) + 1;
for (i = 0; i < delay_cnt; i++) {
if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT)) if (!(tr32(GRC_RX_CPU_EVENT) & GRC_RX_CPU_DRIVER_EVENT))
break; break;
udelay(10); udelay(8);
} }
} }
...@@ -1075,9 +1105,7 @@ static void tg3_ump_link_report(struct tg3 *tp) ...@@ -1075,9 +1105,7 @@ static void tg3_ump_link_report(struct tg3 *tp)
val = 0; val = 0;
tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val); tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX + 12, val);
val = tr32(GRC_RX_CPU_EVENT); tg3_generate_fw_event(tp);
val |= GRC_RX_CPU_DRIVER_EVENT;
tw32_f(GRC_RX_CPU_EVENT, val);
} }
static void tg3_link_report(struct tg3 *tp) static void tg3_link_report(struct tg3 *tp)
...@@ -2124,6 +2152,13 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state) ...@@ -2124,6 +2152,13 @@ static int tg3_set_power_state(struct tg3 *tp, pci_power_t state)
(tp->tg3_flags & TG3_FLAG_WOL_ENABLE)) (tp->tg3_flags & TG3_FLAG_WOL_ENABLE))
mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE; mac_mode |= MAC_MODE_MAGIC_PKT_ENABLE;
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
mac_mode |= tp->mac_mode &
(MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
if (mac_mode & MAC_MODE_APE_TX_EN)
mac_mode |= MAC_MODE_TDE_ENABLE;
}
tw32_f(MAC_MODE, mac_mode); tw32_f(MAC_MODE, mac_mode);
udelay(100); udelay(100);
...@@ -5493,7 +5528,7 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event) ...@@ -5493,7 +5528,7 @@ static void tg3_ape_send_event(struct tg3 *tp, u32 event)
return; return;
apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS); apedata = tg3_ape_read32(tp, TG3_APE_FW_STATUS);
if (apedata != APE_FW_STATUS_READY) if (!(apedata & APE_FW_STATUS_READY))
return; return;
/* Wait for up to 1 millisecond for APE to service previous event. */ /* Wait for up to 1 millisecond for APE to service previous event. */
...@@ -5760,6 +5795,8 @@ static int tg3_chip_reset(struct tg3 *tp) ...@@ -5760,6 +5795,8 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_mdio_stop(tp); tg3_mdio_stop(tp);
tg3_ape_lock(tp, TG3_APE_LOCK_GRC);
/* No matching tg3_nvram_unlock() after this because /* No matching tg3_nvram_unlock() after this because
* chip reset below will undo the nvram lock. * chip reset below will undo the nvram lock.
*/ */
...@@ -5908,12 +5945,19 @@ static int tg3_chip_reset(struct tg3 *tp) ...@@ -5908,12 +5945,19 @@ static int tg3_chip_reset(struct tg3 *tp)
} else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) { } else if (tp->tg3_flags2 & TG3_FLG2_MII_SERDES) {
tp->mac_mode = MAC_MODE_PORT_MODE_GMII; tp->mac_mode = MAC_MODE_PORT_MODE_GMII;
tw32_f(MAC_MODE, tp->mac_mode); tw32_f(MAC_MODE, tp->mac_mode);
} else if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE) {
tp->mac_mode &= (MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN);
if (tp->mac_mode & MAC_MODE_APE_TX_EN)
tp->mac_mode |= MAC_MODE_TDE_ENABLE;
tw32_f(MAC_MODE, tp->mac_mode);
} else } else
tw32_f(MAC_MODE, 0); tw32_f(MAC_MODE, 0);
udelay(40); udelay(40);
tg3_mdio_start(tp); tg3_mdio_start(tp);
tg3_ape_unlock(tp, TG3_APE_LOCK_GRC);
err = tg3_poll_fw(tp); err = tg3_poll_fw(tp);
if (err) if (err)
return err; return err;
...@@ -5935,6 +5979,7 @@ static int tg3_chip_reset(struct tg3 *tp) ...@@ -5935,6 +5979,7 @@ static int tg3_chip_reset(struct tg3 *tp)
tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg); tg3_read_mem(tp, NIC_SRAM_DATA_CFG, &nic_cfg);
if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) { if (nic_cfg & NIC_SRAM_DATA_CFG_ASF_ENABLE) {
tp->tg3_flags |= TG3_FLAG_ENABLE_ASF; tp->tg3_flags |= TG3_FLAG_ENABLE_ASF;
tp->last_event_jiffies = jiffies;
if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS) if (tp->tg3_flags2 & TG3_FLG2_5750_PLUS)
tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE; tp->tg3_flags2 |= TG3_FLG2_ASF_NEW_HANDSHAKE;
} }
...@@ -5948,15 +5993,12 @@ static void tg3_stop_fw(struct tg3 *tp) ...@@ -5948,15 +5993,12 @@ static void tg3_stop_fw(struct tg3 *tp)
{ {
if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) && if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
!(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) { !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
u32 val;
/* Wait for RX cpu to ACK the previous event. */ /* Wait for RX cpu to ACK the previous event. */
tg3_wait_for_event_ack(tp); tg3_wait_for_event_ack(tp);
tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW); tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_PAUSE_FW);
val = tr32(GRC_RX_CPU_EVENT);
val |= GRC_RX_CPU_DRIVER_EVENT; tg3_generate_fw_event(tp);
tw32(GRC_RX_CPU_EVENT, val);
/* Wait for RX cpu to ACK this event. */ /* Wait for RX cpu to ACK this event. */
tg3_wait_for_event_ack(tp); tg3_wait_for_event_ack(tp);
...@@ -7406,7 +7448,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) ...@@ -7406,7 +7448,11 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy)
udelay(10); udelay(10);
} }
tp->mac_mode = MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE | if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
tp->mac_mode &= MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
else
tp->mac_mode = 0;
tp->mac_mode |= MAC_MODE_TXSTAT_ENABLE | MAC_MODE_RXSTAT_ENABLE |
MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE; MAC_MODE_TDE_ENABLE | MAC_MODE_RDE_ENABLE | MAC_MODE_FHDE_ENABLE;
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) && if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) && !(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) &&
...@@ -7840,9 +7886,8 @@ static void tg3_timer(unsigned long __opaque) ...@@ -7840,9 +7886,8 @@ static void tg3_timer(unsigned long __opaque)
* resets. * resets.
*/ */
if (!--tp->asf_counter) { if (!--tp->asf_counter) {
if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) { if ((tp->tg3_flags & TG3_FLAG_ENABLE_ASF) &&
u32 val; !(tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)) {
tg3_wait_for_event_ack(tp); tg3_wait_for_event_ack(tp);
tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX,
...@@ -7850,9 +7895,8 @@ static void tg3_timer(unsigned long __opaque) ...@@ -7850,9 +7895,8 @@ static void tg3_timer(unsigned long __opaque)
tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4); tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
/* 5 seconds timeout */ /* 5 seconds timeout */
tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5); tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
val = tr32(GRC_RX_CPU_EVENT);
val |= GRC_RX_CPU_DRIVER_EVENT; tg3_generate_fw_event(tp);
tw32_f(GRC_RX_CPU_EVENT, val);
} }
tp->asf_counter = tp->asf_multiplier; tp->asf_counter = tp->asf_multiplier;
} }
...@@ -8422,6 +8466,11 @@ static inline unsigned long get_stat64(tg3_stat64_t *val) ...@@ -8422,6 +8466,11 @@ static inline unsigned long get_stat64(tg3_stat64_t *val)
return ret; return ret;
} }
static inline u64 get_estat64(tg3_stat64_t *val)
{
return ((u64)val->high << 32) | ((u64)val->low);
}
static unsigned long calc_crc_errors(struct tg3 *tp) static unsigned long calc_crc_errors(struct tg3 *tp)
{ {
struct tg3_hw_stats *hw_stats = tp->hw_stats; struct tg3_hw_stats *hw_stats = tp->hw_stats;
...@@ -8450,7 +8499,7 @@ static unsigned long calc_crc_errors(struct tg3 *tp) ...@@ -8450,7 +8499,7 @@ static unsigned long calc_crc_errors(struct tg3 *tp)
#define ESTAT_ADD(member) \ #define ESTAT_ADD(member) \
estats->member = old_estats->member + \ estats->member = old_estats->member + \
get_stat64(&hw_stats->member) get_estat64(&hw_stats->member)
static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp) static struct tg3_ethtool_stats *tg3_get_estats(struct tg3 *tp)
{ {
...@@ -12416,6 +12465,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) ...@@ -12416,6 +12465,13 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
tp->misc_host_ctrl); tp->misc_host_ctrl);
} }
/* Preserve the APE MAC_MODE bits */
if (tp->tg3_flags3 & TG3_FLG3_ENABLE_APE)
tp->mac_mode = tr32(MAC_MODE) |
MAC_MODE_APE_TX_EN | MAC_MODE_APE_RX_EN;
else
tp->mac_mode = TG3_DEF_MAC_MODE;
/* these are limited to 10/100 only */ /* these are limited to 10/100 only */
if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 && if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5703 &&
(grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) || (grc_misc_cfg == 0x8000 || grc_misc_cfg == 0x4000)) ||
...@@ -13275,7 +13331,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, ...@@ -13275,7 +13331,6 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
tp->pdev = pdev; tp->pdev = pdev;
tp->dev = dev; tp->dev = dev;
tp->pm_cap = pm_cap; tp->pm_cap = pm_cap;
tp->mac_mode = TG3_DEF_MAC_MODE;
tp->rx_mode = TG3_DEF_RX_MODE; tp->rx_mode = TG3_DEF_RX_MODE;
tp->tx_mode = TG3_DEF_TX_MODE; tp->tx_mode = TG3_DEF_TX_MODE;
......
...@@ -325,6 +325,8 @@ ...@@ -325,6 +325,8 @@
#define MAC_MODE_TDE_ENABLE 0x00200000 #define MAC_MODE_TDE_ENABLE 0x00200000
#define MAC_MODE_RDE_ENABLE 0x00400000 #define MAC_MODE_RDE_ENABLE 0x00400000
#define MAC_MODE_FHDE_ENABLE 0x00800000 #define MAC_MODE_FHDE_ENABLE 0x00800000
#define MAC_MODE_APE_RX_EN 0x08000000
#define MAC_MODE_APE_TX_EN 0x10000000
#define MAC_STATUS 0x00000404 #define MAC_STATUS 0x00000404
#define MAC_STATUS_PCS_SYNCED 0x00000001 #define MAC_STATUS_PCS_SYNCED 0x00000001
#define MAC_STATUS_SIGNAL_DET 0x00000002 #define MAC_STATUS_SIGNAL_DET 0x00000002
...@@ -1889,6 +1891,7 @@ ...@@ -1889,6 +1891,7 @@
#define APE_EVENT_STATUS_EVENT_PENDING 0x80000000 #define APE_EVENT_STATUS_EVENT_PENDING 0x80000000
/* APE convenience enumerations. */ /* APE convenience enumerations. */
#define TG3_APE_LOCK_GRC 1
#define TG3_APE_LOCK_MEM 4 #define TG3_APE_LOCK_MEM 4
#define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10 #define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10
...@@ -2429,7 +2432,10 @@ struct tg3 { ...@@ -2429,7 +2432,10 @@ struct tg3 {
struct tg3_ethtool_stats estats; struct tg3_ethtool_stats estats;
struct tg3_ethtool_stats estats_prev; struct tg3_ethtool_stats estats_prev;
union {
unsigned long phy_crc_errors; unsigned long phy_crc_errors;
unsigned long last_event_jiffies;
};
u32 rx_offset; u32 rx_offset;
u32 tg3_flags; u32 tg3_flags;
......
...@@ -80,7 +80,8 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, ...@@ -80,7 +80,8 @@ extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
struct net_device *dev, struct net_device *dev,
int strict); int strict);
extern int ipv6_dev_get_saddr(struct net_device *dev, extern int ipv6_dev_get_saddr(struct net *net,
struct net_device *dev,
const struct in6_addr *daddr, const struct in6_addr *daddr,
unsigned int srcprefs, unsigned int srcprefs,
struct in6_addr *saddr); struct in6_addr *saddr);
......
...@@ -107,6 +107,7 @@ struct rt6_rtnl_dump_arg ...@@ -107,6 +107,7 @@ struct rt6_rtnl_dump_arg
{ {
struct sk_buff *skb; struct sk_buff *skb;
struct netlink_callback *cb; struct netlink_callback *cb;
struct net *net;
}; };
extern int rt6_dump_route(struct rt6_info *rt, void *p_arg); extern int rt6_dump_route(struct rt6_info *rt, void *p_arg);
......
...@@ -2914,6 +2914,68 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, ...@@ -2914,6 +2914,68 @@ static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
return 0; return 0;
} }
static void rt_secret_reschedule(int old)
{
struct net *net;
int new = ip_rt_secret_interval;
int diff = new - old;
if (!diff)
return;
rtnl_lock();
for_each_net(net) {
int deleted = del_timer_sync(&net->ipv4.rt_secret_timer);
if (!new)
continue;
if (deleted) {
long time = net->ipv4.rt_secret_timer.expires - jiffies;
if (time <= 0 || (time += diff) <= 0)
time = 0;
net->ipv4.rt_secret_timer.expires = time;
} else
net->ipv4.rt_secret_timer.expires = new;
net->ipv4.rt_secret_timer.expires += jiffies;
add_timer(&net->ipv4.rt_secret_timer);
}
rtnl_unlock();
}
static int ipv4_sysctl_rt_secret_interval(ctl_table *ctl, int write,
struct file *filp,
void __user *buffer, size_t *lenp,
loff_t *ppos)
{
int old = ip_rt_secret_interval;
int ret = proc_dointvec_jiffies(ctl, write, filp, buffer, lenp, ppos);
rt_secret_reschedule(old);
return ret;
}
static int ipv4_sysctl_rt_secret_interval_strategy(ctl_table *table,
int __user *name,
int nlen,
void __user *oldval,
size_t __user *oldlenp,
void __user *newval,
size_t newlen)
{
int old = ip_rt_secret_interval;
int ret = sysctl_jiffies(table, name, nlen, oldval, oldlenp, newval,
newlen);
rt_secret_reschedule(old);
return ret;
}
static ctl_table ipv4_route_table[] = { static ctl_table ipv4_route_table[] = {
{ {
.ctl_name = NET_IPV4_ROUTE_GC_THRESH, .ctl_name = NET_IPV4_ROUTE_GC_THRESH,
...@@ -3048,8 +3110,8 @@ static ctl_table ipv4_route_table[] = { ...@@ -3048,8 +3110,8 @@ static ctl_table ipv4_route_table[] = {
.data = &ip_rt_secret_interval, .data = &ip_rt_secret_interval,
.maxlen = sizeof(int), .maxlen = sizeof(int),
.mode = 0644, .mode = 0644,
.proc_handler = &proc_dointvec_jiffies, .proc_handler = &ipv4_sysctl_rt_secret_interval,
.strategy = &sysctl_jiffies, .strategy = &ipv4_sysctl_rt_secret_interval_strategy,
}, },
{ .ctl_name = 0 } { .ctl_name = 0 }
}; };
...@@ -3126,10 +3188,12 @@ static __net_init int rt_secret_timer_init(struct net *net) ...@@ -3126,10 +3188,12 @@ static __net_init int rt_secret_timer_init(struct net *net)
net->ipv4.rt_secret_timer.data = (unsigned long)net; net->ipv4.rt_secret_timer.data = (unsigned long)net;
init_timer_deferrable(&net->ipv4.rt_secret_timer); init_timer_deferrable(&net->ipv4.rt_secret_timer);
net->ipv4.rt_secret_timer.expires = if (ip_rt_secret_interval) {
jiffies + net_random() % ip_rt_secret_interval + net->ipv4.rt_secret_timer.expires =
ip_rt_secret_interval; jiffies + net_random() % ip_rt_secret_interval +
add_timer(&net->ipv4.rt_secret_timer); ip_rt_secret_interval;
add_timer(&net->ipv4.rt_secret_timer);
}
return 0; return 0;
} }
......
...@@ -1106,13 +1106,12 @@ static int ipv6_get_saddr_eval(struct net *net, ...@@ -1106,13 +1106,12 @@ static int ipv6_get_saddr_eval(struct net *net,
return ret; return ret;
} }
int ipv6_dev_get_saddr(struct net_device *dst_dev, int ipv6_dev_get_saddr(struct net *net, struct net_device *dst_dev,
const struct in6_addr *daddr, unsigned int prefs, const struct in6_addr *daddr, unsigned int prefs,
struct in6_addr *saddr) struct in6_addr *saddr)
{ {
struct ipv6_saddr_score scores[2], struct ipv6_saddr_score scores[2],
*score = &scores[0], *hiscore = &scores[1]; *score = &scores[0], *hiscore = &scores[1];
struct net *net = dev_net(dst_dev);
struct ipv6_saddr_dst dst; struct ipv6_saddr_dst dst;
struct net_device *dev; struct net_device *dev;
int dst_type; int dst_type;
......
...@@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp, ...@@ -93,7 +93,8 @@ static int fib6_rule_action(struct fib_rule *rule, struct flowi *flp,
if (flags & RT6_LOOKUP_F_SRCPREF_COA) if (flags & RT6_LOOKUP_F_SRCPREF_COA)
srcprefs |= IPV6_PREFER_SRC_COA; srcprefs |= IPV6_PREFER_SRC_COA;
if (ipv6_dev_get_saddr(ip6_dst_idev(&rt->u.dst)->dev, if (ipv6_dev_get_saddr(net,
ip6_dst_idev(&rt->u.dst)->dev,
&flp->fl6_dst, srcprefs, &flp->fl6_dst, srcprefs,
&saddr)) &saddr))
goto again; goto again;
......
...@@ -378,6 +378,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb) ...@@ -378,6 +378,7 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
arg.skb = skb; arg.skb = skb;
arg.cb = cb; arg.cb = cb;
arg.net = net;
w->args = &arg; w->args = &arg;
for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) { for (h = s_h; h < FIB_TABLE_HASHSZ; h++, s_e = 0) {
......
...@@ -934,7 +934,7 @@ static int ip6_dst_lookup_tail(struct sock *sk, ...@@ -934,7 +934,7 @@ static int ip6_dst_lookup_tail(struct sock *sk,
goto out_err_release; goto out_err_release;
if (ipv6_addr_any(&fl->fl6_src)) { if (ipv6_addr_any(&fl->fl6_src)) {
err = ipv6_dev_get_saddr(ip6_dst_idev(*dst)->dev, err = ipv6_dev_get_saddr(net, ip6_dst_idev(*dst)->dev,
&fl->fl6_dst, &fl->fl6_dst,
sk ? inet6_sk(sk)->srcprefs : 0, sk ? inet6_sk(sk)->srcprefs : 0,
&fl->fl6_src); &fl->fl6_src);
......
...@@ -549,7 +549,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, ...@@ -549,7 +549,7 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
override = 0; override = 0;
in6_ifa_put(ifp); in6_ifa_put(ifp);
} else { } else {
if (ipv6_dev_get_saddr(dev, daddr, if (ipv6_dev_get_saddr(dev_net(dev), dev, daddr,
inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs, inet6_sk(dev_net(dev)->ipv6.ndisc_sk)->srcprefs,
&tmpaddr)) &tmpaddr))
return; return;
......
...@@ -2106,7 +2106,8 @@ static inline size_t rt6_nlmsg_size(void) ...@@ -2106,7 +2106,8 @@ static inline size_t rt6_nlmsg_size(void)
+ nla_total_size(sizeof(struct rta_cacheinfo)); + nla_total_size(sizeof(struct rta_cacheinfo));
} }
static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, static int rt6_fill_node(struct net *net,
struct sk_buff *skb, struct rt6_info *rt,
struct in6_addr *dst, struct in6_addr *src, struct in6_addr *dst, struct in6_addr *src,
int iif, int type, u32 pid, u32 seq, int iif, int type, u32 pid, u32 seq,
int prefix, int nowait, unsigned int flags) int prefix, int nowait, unsigned int flags)
...@@ -2189,7 +2190,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, ...@@ -2189,7 +2190,7 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
} else if (dst) { } else if (dst) {
struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst); struct inet6_dev *idev = ip6_dst_idev(&rt->u.dst);
struct in6_addr saddr_buf; struct in6_addr saddr_buf;
if (ipv6_dev_get_saddr(idev ? idev->dev : NULL, if (ipv6_dev_get_saddr(net, idev ? idev->dev : NULL,
dst, 0, &saddr_buf) == 0) dst, 0, &saddr_buf) == 0)
NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
} }
...@@ -2234,7 +2235,8 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg) ...@@ -2234,7 +2235,8 @@ int rt6_dump_route(struct rt6_info *rt, void *p_arg)
} else } else
prefix = 0; prefix = 0;
return rt6_fill_node(arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE, return rt6_fill_node(arg->net,
arg->skb, rt, NULL, NULL, 0, RTM_NEWROUTE,
NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq, NETLINK_CB(arg->cb->skb).pid, arg->cb->nlh->nlmsg_seq,
prefix, 0, NLM_F_MULTI); prefix, 0, NLM_F_MULTI);
} }
...@@ -2300,7 +2302,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void ...@@ -2300,7 +2302,7 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl); rt = (struct rt6_info*) ip6_route_output(net, NULL, &fl);
skb->dst = &rt->u.dst; skb->dst = &rt->u.dst;
err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif, err = rt6_fill_node(net, skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
RTM_NEWROUTE, NETLINK_CB(in_skb).pid, RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
nlh->nlmsg_seq, 0, 0, 0); nlh->nlmsg_seq, 0, 0, 0);
if (err < 0) { if (err < 0) {
...@@ -2327,7 +2329,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info) ...@@ -2327,7 +2329,7 @@ void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
if (skb == NULL) if (skb == NULL)
goto errout; goto errout;
err = rt6_fill_node(skb, rt, NULL, NULL, 0, err = rt6_fill_node(net, skb, rt, NULL, NULL, 0,
event, info->pid, seq, 0, 0, 0); event, info->pid, seq, 0, 0, 0);
if (err < 0) { if (err < 0) {
/* -EMSGSIZE implies BUG in rt6_nlmsg_size() */ /* -EMSGSIZE implies BUG in rt6_nlmsg_size() */
......
...@@ -52,12 +52,14 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr, ...@@ -52,12 +52,14 @@ static struct dst_entry *xfrm6_dst_lookup(int tos, xfrm_address_t *saddr,
static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr) static int xfrm6_get_saddr(xfrm_address_t *saddr, xfrm_address_t *daddr)
{ {
struct dst_entry *dst; struct dst_entry *dst;
struct net_device *dev;
dst = xfrm6_dst_lookup(0, NULL, daddr); dst = xfrm6_dst_lookup(0, NULL, daddr);
if (IS_ERR(dst)) if (IS_ERR(dst))
return -EHOSTUNREACH; return -EHOSTUNREACH;
ipv6_dev_get_saddr(ip6_dst_idev(dst)->dev, dev = ip6_dst_idev(dst)->dev;
ipv6_dev_get_saddr(dev_net(dev), dev,
(struct in6_addr *)&daddr->a6, 0, (struct in6_addr *)&daddr->a6, 0,
(struct in6_addr *)&saddr->a6); (struct in6_addr *)&saddr->a6);
dst_release(dst); dst_release(dst);
......
...@@ -280,7 +280,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg) ...@@ -280,7 +280,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) { if (n->nlmsg_type == RTM_DELTFILTER && t->tcm_handle == 0) {
spin_lock_bh(root_lock); spin_lock_bh(root_lock);
*back = tp->next; *back = tp->next;
spin_lock_bh(root_lock); spin_unlock_bh(root_lock);
tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER); tfilter_notify(skb, n, tp, fh, RTM_DELTFILTER);
tcf_destroy(tp); tcf_destroy(tp);
......
...@@ -319,7 +319,8 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk, ...@@ -319,7 +319,8 @@ static void sctp_v6_get_saddr(struct sctp_sock *sk,
__func__, asoc, dst, NIP6(daddr->v6.sin6_addr)); __func__, asoc, dst, NIP6(daddr->v6.sin6_addr));
if (!asoc) { if (!asoc) {
ipv6_dev_get_saddr(dst ? ip6_dst_idev(dst)->dev : NULL, ipv6_dev_get_saddr(sock_net(sctp_opt2sk(sk)),
dst ? ip6_dst_idev(dst)->dev : NULL,
&daddr->v6.sin6_addr, &daddr->v6.sin6_addr,
inet6_sk(&sk->inet.sk)->srcprefs, inet6_sk(&sk->inet.sk)->srcprefs,
&saddr->v6.sin6_addr); &saddr->v6.sin6_addr);
......
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