Commit 4880d109 authored by Linus Torvalds's avatar Linus Torvalds

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

* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6:
  net_cls_act: act_simple dont ignore realloc code
  iwlwifi: make IWLWIFI a tristate
  Revert "atm: Do not free already unregistered net device."
  dccp: return -EINVAL on invalid feature length
  irda: fix !PNP support for drivers/net/irda/smsc-ircc2.c
  irda: fix !PNP support in drivers/net/irda/nsc-ircc.c
  net_cls_act: Make act_simple use of netlink policy.
  ip: Use inline function dst_metric() instead of direct access to dst->metric[]
  ip: Make use of the inline function dst_metric_locked()
  atm: Bad locking on br2684_devs modifications.
  atm: Do not free already unregistered net device.
  mac80211: Do not free net device after it is unregistered.
  bridge: Consolidate error paths in br_add_bridge().
  bridge: Net device leak in br_add_bridge().
  niu: Fix probing regression for maramba on-board chips.
  lapbeth: Release ->ethdev when unregistering device.
  xfrm: convert empty xfrm_audit_* macros to functions
  net: Fix useless comment reference loop.
  sch_htb: remove from event queue in htb_parent_to_leaf()
parents a1530636 9d1045ad
...@@ -100,7 +100,9 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info); ...@@ -100,7 +100,9 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info);
static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_108(nsc_chip_t *chip, chipio_t *info);
static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_338(nsc_chip_t *chip, chipio_t *info);
static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info); static int nsc_ircc_init_39x(nsc_chip_t *chip, chipio_t *info);
#ifdef CONFIG_PNP
static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id); static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id);
#endif
/* These are the known NSC chips */ /* These are the known NSC chips */
static nsc_chip_t chips[] = { static nsc_chip_t chips[] = {
...@@ -156,9 +158,11 @@ static const struct pnp_device_id nsc_ircc_pnp_table[] = { ...@@ -156,9 +158,11 @@ static const struct pnp_device_id nsc_ircc_pnp_table[] = {
MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table); MODULE_DEVICE_TABLE(pnp, nsc_ircc_pnp_table);
static struct pnp_driver nsc_ircc_pnp_driver = { static struct pnp_driver nsc_ircc_pnp_driver = {
#ifdef CONFIG_PNP
.name = "nsc-ircc", .name = "nsc-ircc",
.id_table = nsc_ircc_pnp_table, .id_table = nsc_ircc_pnp_table,
.probe = nsc_ircc_pnp_probe, .probe = nsc_ircc_pnp_probe,
#endif
}; };
/* Some prototypes */ /* Some prototypes */
...@@ -916,6 +920,7 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info) ...@@ -916,6 +920,7 @@ static int nsc_ircc_probe_39x(nsc_chip_t *chip, chipio_t *info)
return 0; return 0;
} }
#ifdef CONFIG_PNP
/* PNP probing */ /* PNP probing */
static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id) static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *id)
{ {
...@@ -952,6 +957,7 @@ static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *i ...@@ -952,6 +957,7 @@ static int nsc_ircc_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *i
return 0; return 0;
} }
#endif
/* /*
* Function nsc_ircc_setup (info) * Function nsc_ircc_setup (info)
......
...@@ -376,6 +376,7 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table); ...@@ -376,6 +376,7 @@ MODULE_DEVICE_TABLE(pnp, smsc_ircc_pnp_table);
static int pnp_driver_registered; static int pnp_driver_registered;
#ifdef CONFIG_PNP
static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev, static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev,
const struct pnp_device_id *dev_id) const struct pnp_device_id *dev_id)
{ {
...@@ -402,7 +403,9 @@ static struct pnp_driver smsc_ircc_pnp_driver = { ...@@ -402,7 +403,9 @@ static struct pnp_driver smsc_ircc_pnp_driver = {
.id_table = smsc_ircc_pnp_table, .id_table = smsc_ircc_pnp_table,
.probe = smsc_ircc_pnp_probe, .probe = smsc_ircc_pnp_probe,
}; };
#else /* CONFIG_PNP */
static struct pnp_driver smsc_ircc_pnp_driver;
#endif
/******************************************************************************* /*******************************************************************************
* *
......
/* niu.c: Neptune ethernet driver. /* niu.c: Neptune ethernet driver.
* *
* Copyright (C) 2007 David S. Miller (davem@davemloft.net) * Copyright (C) 2007, 2008 David S. Miller (davem@davemloft.net)
*/ */
#include <linux/module.h> #include <linux/module.h>
...@@ -33,8 +33,8 @@ ...@@ -33,8 +33,8 @@
#define DRV_MODULE_NAME "niu" #define DRV_MODULE_NAME "niu"
#define PFX DRV_MODULE_NAME ": " #define PFX DRV_MODULE_NAME ": "
#define DRV_MODULE_VERSION "0.8" #define DRV_MODULE_VERSION "0.9"
#define DRV_MODULE_RELDATE "April 24, 2008" #define DRV_MODULE_RELDATE "May 4, 2008"
static char version[] __devinitdata = static char version[] __devinitdata =
DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
...@@ -7264,8 +7264,11 @@ static int __devinit niu_get_and_validate_port(struct niu *np) ...@@ -7264,8 +7264,11 @@ static int __devinit niu_get_and_validate_port(struct niu *np)
parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) & parent->num_ports = nr64(ESPC_NUM_PORTS_MACS) &
ESPC_NUM_PORTS_MACS_VAL; ESPC_NUM_PORTS_MACS_VAL;
/* All of the current probing methods fail on
* Maramba on-board parts.
*/
if (!parent->num_ports) if (!parent->num_ports)
return -ENODEV; parent->num_ports = 4;
} }
} }
} }
......
...@@ -459,6 +459,7 @@ static void __exit lapbeth_cleanup_driver(void) ...@@ -459,6 +459,7 @@ static void __exit lapbeth_cleanup_driver(void)
list_for_each_safe(entry, tmp, &lapbeth_devices) { list_for_each_safe(entry, tmp, &lapbeth_devices) {
lapbeth = list_entry(entry, struct lapbethdev, node); lapbeth = list_entry(entry, struct lapbethdev, node);
dev_put(lapbeth->ethdev);
unregister_netdevice(lapbeth->axdev); unregister_netdevice(lapbeth->axdev);
} }
rtnl_unlock(); rtnl_unlock();
......
config IWLWIFI config IWLWIFI
bool tristate
default n
config IWLCORE config IWLCORE
tristate "Intel Wireless Wifi Core" tristate "Intel Wireless Wifi Core"
......
...@@ -210,7 +210,7 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst) ...@@ -210,7 +210,7 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst)
{ {
return (inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO || return (inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO ||
(inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT && (inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT &&
!(dst_metric(dst, RTAX_LOCK)&(1<<RTAX_MTU)))); !(dst_metric_locked(dst, RTAX_MTU))));
} }
extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more); extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more);
......
...@@ -648,14 +648,46 @@ extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family, ...@@ -648,14 +648,46 @@ extern void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
extern void xfrm_audit_state_icvfail(struct xfrm_state *x, extern void xfrm_audit_state_icvfail(struct xfrm_state *x,
struct sk_buff *skb, u8 proto); struct sk_buff *skb, u8 proto);
#else #else
#define xfrm_audit_policy_add(x, r, a, se, s) do { ; } while (0)
#define xfrm_audit_policy_delete(x, r, a, se, s) do { ; } while (0) static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
#define xfrm_audit_state_add(x, r, a, se, s) do { ; } while (0) u32 auid, u32 ses, u32 secid)
#define xfrm_audit_state_delete(x, r, a, se, s) do { ; } while (0) {
#define xfrm_audit_state_replay_overflow(x, s) do { ; } while (0) }
#define xfrm_audit_state_notfound_simple(s, f) do { ; } while (0)
#define xfrm_audit_state_notfound(s, f, sp, sq) do { ; } while (0) static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
#define xfrm_audit_state_icvfail(x, s, p) do { ; } while (0) u32 auid, u32 ses, u32 secid)
{
}
static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
u32 auid, u32 ses, u32 secid)
{
}
static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
u32 auid, u32 ses, u32 secid)
{
}
static inline void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
struct sk_buff *skb)
{
}
static inline void xfrm_audit_state_notfound_simple(struct sk_buff *skb,
u16 family)
{
}
static inline void xfrm_audit_state_notfound(struct sk_buff *skb, u16 family,
__be32 net_spi, __be32 net_seq)
{
}
static inline void xfrm_audit_state_icvfail(struct xfrm_state *x,
struct sk_buff *skb, u8 proto)
{
}
#endif /* CONFIG_AUDITSYSCALL */ #endif /* CONFIG_AUDITSYSCALL */
static inline void xfrm_pol_hold(struct xfrm_policy *policy) static inline void xfrm_pol_hold(struct xfrm_policy *policy)
......
...@@ -346,9 +346,9 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb) ...@@ -346,9 +346,9 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
/* skb==NULL means VCC is being destroyed */ /* skb==NULL means VCC is being destroyed */
br2684_close_vcc(brvcc); br2684_close_vcc(brvcc);
if (list_empty(&brdev->brvccs)) { if (list_empty(&brdev->brvccs)) {
read_lock(&devs_lock); write_lock_irq(&devs_lock);
list_del(&brdev->br2684_devs); list_del(&brdev->br2684_devs);
read_unlock(&devs_lock); write_unlock_irq(&devs_lock);
unregister_netdev(net_dev); unregister_netdev(net_dev);
free_netdev(net_dev); free_netdev(net_dev);
} }
......
...@@ -273,15 +273,13 @@ int br_add_bridge(const char *name) ...@@ -273,15 +273,13 @@ int br_add_bridge(const char *name)
rtnl_lock(); rtnl_lock();
if (strchr(dev->name, '%')) { if (strchr(dev->name, '%')) {
ret = dev_alloc_name(dev, dev->name); ret = dev_alloc_name(dev, dev->name);
if (ret < 0) { if (ret < 0)
free_netdev(dev); goto out_free;
goto out;
}
} }
ret = register_netdevice(dev); ret = register_netdevice(dev);
if (ret) if (ret)
goto out; goto out_free;
ret = br_sysfs_addbr(dev); ret = br_sysfs_addbr(dev);
if (ret) if (ret)
...@@ -289,6 +287,10 @@ int br_add_bridge(const char *name) ...@@ -289,6 +287,10 @@ int br_add_bridge(const char *name)
out: out:
rtnl_unlock(); rtnl_unlock();
return ret; return ret;
out_free:
free_netdev(dev);
goto out;
} }
int br_del_bridge(const char *name) int br_del_bridge(const char *name)
......
...@@ -200,7 +200,9 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask, ...@@ -200,7 +200,9 @@ struct sk_buff *__alloc_skb(unsigned int size, gfp_t gfp_mask,
goto nodata; goto nodata;
/* /*
* See comment in sk_buff definition, just before the 'tail' member * Only clear those fields we need to clear, not those that we will
* actually initialise below. Hence, don't put any more fields after
* the tail pointer in struct sk_buff!
*/ */
memset(skb, 0, offsetof(struct sk_buff, tail)); memset(skb, 0, offsetof(struct sk_buff, tail));
skb->truesize = size + sizeof(struct sk_buff); skb->truesize = size + sizeof(struct sk_buff);
......
...@@ -32,7 +32,7 @@ int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature, ...@@ -32,7 +32,7 @@ int dccp_feat_change(struct dccp_minisock *dmsk, u8 type, u8 feature,
if (len > 3) { if (len > 3) {
DCCP_WARN("invalid length %d\n", len); DCCP_WARN("invalid length %d\n", len);
return 1; return -EINVAL;
} }
/* XXX add further sanity checks */ /* XXX add further sanity checks */
......
...@@ -235,14 +235,14 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu) ...@@ -235,14 +235,14 @@ static void dn_dst_update_pmtu(struct dst_entry *dst, u32 mtu)
else else
min_mtu -= 21; min_mtu -= 21;
if (dst->metrics[RTAX_MTU-1] > mtu && mtu >= min_mtu) { if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= min_mtu) {
if (!(dst_metric_locked(dst, RTAX_MTU))) { if (!(dst_metric_locked(dst, RTAX_MTU))) {
dst->metrics[RTAX_MTU-1] = mtu; dst->metrics[RTAX_MTU-1] = mtu;
dst_set_expires(dst, dn_rt_mtu_expires); dst_set_expires(dst, dn_rt_mtu_expires);
} }
if (!(dst_metric_locked(dst, RTAX_ADVMSS))) { if (!(dst_metric_locked(dst, RTAX_ADVMSS))) {
u32 mss = mtu - DN_MAX_NSP_DATA_HEADER; u32 mss = mtu - DN_MAX_NSP_DATA_HEADER;
if (dst->metrics[RTAX_ADVMSS-1] > mss) if (dst_metric(dst, RTAX_ADVMSS) > mss)
dst->metrics[RTAX_ADVMSS-1] = mss; dst->metrics[RTAX_ADVMSS-1] = mss;
} }
} }
...@@ -805,12 +805,12 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res) ...@@ -805,12 +805,12 @@ static int dn_rt_set_next_hop(struct dn_route *rt, struct dn_fib_res *res)
rt->u.dst.neighbour = n; rt->u.dst.neighbour = n;
} }
if (rt->u.dst.metrics[RTAX_MTU-1] == 0 || if (dst_metric(&rt->u.dst, RTAX_MTU) == 0 ||
rt->u.dst.metrics[RTAX_MTU-1] > rt->u.dst.dev->mtu) dst_metric(&rt->u.dst, RTAX_MTU) > rt->u.dst.dev->mtu)
rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu; rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu;
mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->u.dst)); mss = dn_mss_from_pmtu(dev, dst_mtu(&rt->u.dst));
if (rt->u.dst.metrics[RTAX_ADVMSS-1] == 0 || if (dst_metric(&rt->u.dst, RTAX_ADVMSS) == 0 ||
rt->u.dst.metrics[RTAX_ADVMSS-1] > mss) dst_metric(&rt->u.dst, RTAX_ADVMSS) > mss)
rt->u.dst.metrics[RTAX_ADVMSS-1] = mss; rt->u.dst.metrics[RTAX_ADVMSS-1] = mss;
return 0; return 0;
} }
......
...@@ -1468,14 +1468,14 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, ...@@ -1468,14 +1468,14 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
/* BSD 4.2 compatibility hack :-( */ /* BSD 4.2 compatibility hack :-( */
if (mtu == 0 && if (mtu == 0 &&
old_mtu >= rth->u.dst.metrics[RTAX_MTU-1] && old_mtu >= dst_metric(&rth->u.dst, RTAX_MTU) &&
old_mtu >= 68 + (iph->ihl << 2)) old_mtu >= 68 + (iph->ihl << 2))
old_mtu -= iph->ihl << 2; old_mtu -= iph->ihl << 2;
mtu = guess_mtu(old_mtu); mtu = guess_mtu(old_mtu);
} }
if (mtu <= rth->u.dst.metrics[RTAX_MTU-1]) { if (mtu <= dst_metric(&rth->u.dst, RTAX_MTU)) {
if (mtu < rth->u.dst.metrics[RTAX_MTU-1]) { if (mtu < dst_metric(&rth->u.dst, RTAX_MTU)) {
dst_confirm(&rth->u.dst); dst_confirm(&rth->u.dst);
if (mtu < ip_rt_min_pmtu) { if (mtu < ip_rt_min_pmtu) {
mtu = ip_rt_min_pmtu; mtu = ip_rt_min_pmtu;
...@@ -1497,7 +1497,7 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph, ...@@ -1497,7 +1497,7 @@ unsigned short ip_rt_frag_needed(struct net *net, struct iphdr *iph,
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu) static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
{ {
if (dst->metrics[RTAX_MTU-1] > mtu && mtu >= 68 && if (dst_metric(dst, RTAX_MTU) > mtu && mtu >= 68 &&
!(dst_metric_locked(dst, RTAX_MTU))) { !(dst_metric_locked(dst, RTAX_MTU))) {
if (mtu < ip_rt_min_pmtu) { if (mtu < ip_rt_min_pmtu) {
mtu = ip_rt_min_pmtu; mtu = ip_rt_min_pmtu;
...@@ -1613,7 +1613,7 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) ...@@ -1613,7 +1613,7 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
sizeof(rt->u.dst.metrics)); sizeof(rt->u.dst.metrics));
if (fi->fib_mtu == 0) { if (fi->fib_mtu == 0) {
rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu; rt->u.dst.metrics[RTAX_MTU-1] = rt->u.dst.dev->mtu;
if (rt->u.dst.metrics[RTAX_LOCK-1] & (1 << RTAX_MTU) && if (dst_metric_locked(&rt->u.dst, RTAX_MTU) &&
rt->rt_gateway != rt->rt_dst && rt->rt_gateway != rt->rt_dst &&
rt->u.dst.dev->mtu > 576) rt->u.dst.dev->mtu > 576)
rt->u.dst.metrics[RTAX_MTU-1] = 576; rt->u.dst.metrics[RTAX_MTU-1] = 576;
...@@ -1624,14 +1624,14 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag) ...@@ -1624,14 +1624,14 @@ static void rt_set_nexthop(struct rtable *rt, struct fib_result *res, u32 itag)
} else } else
rt->u.dst.metrics[RTAX_MTU-1]= rt->u.dst.dev->mtu; rt->u.dst.metrics[RTAX_MTU-1]= rt->u.dst.dev->mtu;
if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0) if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0)
rt->u.dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl; rt->u.dst.metrics[RTAX_HOPLIMIT-1] = sysctl_ip_default_ttl;
if (rt->u.dst.metrics[RTAX_MTU-1] > IP_MAX_MTU) if (dst_metric(&rt->u.dst, RTAX_MTU) > IP_MAX_MTU)
rt->u.dst.metrics[RTAX_MTU-1] = IP_MAX_MTU; rt->u.dst.metrics[RTAX_MTU-1] = IP_MAX_MTU;
if (rt->u.dst.metrics[RTAX_ADVMSS-1] == 0) if (dst_metric(&rt->u.dst, RTAX_ADVMSS) == 0)
rt->u.dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, rt->u.dst.dev->mtu - 40, rt->u.dst.metrics[RTAX_ADVMSS-1] = max_t(unsigned int, rt->u.dst.dev->mtu - 40,
ip_rt_min_advmss); ip_rt_min_advmss);
if (rt->u.dst.metrics[RTAX_ADVMSS-1] > 65535 - 40) if (dst_metric(&rt->u.dst, RTAX_ADVMSS) > 65535 - 40)
rt->u.dst.metrics[RTAX_ADVMSS-1] = 65535 - 40; rt->u.dst.metrics[RTAX_ADVMSS-1] = 65535 - 40;
#ifdef CONFIG_NET_CLS_ROUTE #ifdef CONFIG_NET_CLS_ROUTE
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/sysctl.h> #include <linux/sysctl.h>
#include <net/dst.h>
#include <net/tcp.h> #include <net/tcp.h>
#include <net/inet_common.h> #include <net/inet_common.h>
#include <linux/ipsec.h> #include <linux/ipsec.h>
...@@ -605,7 +606,7 @@ static u32 tcp_rto_min(struct sock *sk) ...@@ -605,7 +606,7 @@ static u32 tcp_rto_min(struct sock *sk)
u32 rto_min = TCP_RTO_MIN; u32 rto_min = TCP_RTO_MIN;
if (dst && dst_metric_locked(dst, RTAX_RTO_MIN)) if (dst && dst_metric_locked(dst, RTAX_RTO_MIN))
rto_min = dst->metrics[RTAX_RTO_MIN - 1]; rto_min = dst_metric(dst, RTAX_RTO_MIN);
return rto_min; return rto_min;
} }
...@@ -769,7 +770,7 @@ void tcp_update_metrics(struct sock *sk) ...@@ -769,7 +770,7 @@ void tcp_update_metrics(struct sock *sk)
dst->metrics[RTAX_RTTVAR - 1] = m; dst->metrics[RTAX_RTTVAR - 1] = m;
else else
dst->metrics[RTAX_RTTVAR-1] -= dst->metrics[RTAX_RTTVAR-1] -=
(dst->metrics[RTAX_RTTVAR-1] - m)>>2; (dst_metric(dst, RTAX_RTTVAR) - m)>>2;
} }
if (tp->snd_ssthresh >= 0xFFFF) { if (tp->snd_ssthresh >= 0xFFFF) {
...@@ -788,21 +789,21 @@ void tcp_update_metrics(struct sock *sk) ...@@ -788,21 +789,21 @@ void tcp_update_metrics(struct sock *sk)
dst->metrics[RTAX_SSTHRESH-1] = dst->metrics[RTAX_SSTHRESH-1] =
max(tp->snd_cwnd >> 1, tp->snd_ssthresh); max(tp->snd_cwnd >> 1, tp->snd_ssthresh);
if (!dst_metric_locked(dst, RTAX_CWND)) if (!dst_metric_locked(dst, RTAX_CWND))
dst->metrics[RTAX_CWND-1] = (dst->metrics[RTAX_CWND-1] + tp->snd_cwnd) >> 1; dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_cwnd) >> 1;
} else { } else {
/* Else slow start did not finish, cwnd is non-sense, /* Else slow start did not finish, cwnd is non-sense,
ssthresh may be also invalid. ssthresh may be also invalid.
*/ */
if (!dst_metric_locked(dst, RTAX_CWND)) if (!dst_metric_locked(dst, RTAX_CWND))
dst->metrics[RTAX_CWND-1] = (dst->metrics[RTAX_CWND-1] + tp->snd_ssthresh) >> 1; dst->metrics[RTAX_CWND-1] = (dst_metric(dst, RTAX_CWND) + tp->snd_ssthresh) >> 1;
if (dst->metrics[RTAX_SSTHRESH-1] && if (dst_metric(dst, RTAX_SSTHRESH) &&
!dst_metric_locked(dst, RTAX_SSTHRESH) && !dst_metric_locked(dst, RTAX_SSTHRESH) &&
tp->snd_ssthresh > dst->metrics[RTAX_SSTHRESH-1]) tp->snd_ssthresh > dst_metric(dst, RTAX_SSTHRESH))
dst->metrics[RTAX_SSTHRESH-1] = tp->snd_ssthresh; dst->metrics[RTAX_SSTHRESH-1] = tp->snd_ssthresh;
} }
if (!dst_metric_locked(dst, RTAX_REORDERING)) { if (!dst_metric_locked(dst, RTAX_REORDERING)) {
if (dst->metrics[RTAX_REORDERING-1] < tp->reordering && if (dst_metric(dst, RTAX_REORDERING) < tp->reordering &&
tp->reordering != sysctl_tcp_reordering) tp->reordering != sysctl_tcp_reordering)
dst->metrics[RTAX_REORDERING-1] = tp->reordering; dst->metrics[RTAX_REORDERING-1] = tp->reordering;
} }
......
...@@ -1243,11 +1243,11 @@ int ip6_route_add(struct fib6_config *cfg) ...@@ -1243,11 +1243,11 @@ int ip6_route_add(struct fib6_config *cfg)
} }
} }
if (rt->u.dst.metrics[RTAX_HOPLIMIT-1] == 0) if (dst_metric(&rt->u.dst, RTAX_HOPLIMIT) == 0)
rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1; rt->u.dst.metrics[RTAX_HOPLIMIT-1] = -1;
if (!rt->u.dst.metrics[RTAX_MTU-1]) if (!dst_metric(&rt->u.dst, RTAX_MTU))
rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev); rt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(dev);
if (!rt->u.dst.metrics[RTAX_ADVMSS-1]) if (!dst_metric(&rt->u.dst, RTAX_ADVMSS))
rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst)); rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(net, dst_mtu(&rt->u.dst));
rt->u.dst.dev = dev; rt->u.dst.dev = dev;
rt->rt6i_idev = idev; rt->rt6i_idev = idev;
......
...@@ -1766,6 +1766,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) ...@@ -1766,6 +1766,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
fail_rate: fail_rate:
ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev)); ieee80211_debugfs_remove_netdev(IEEE80211_DEV_TO_SUB_IF(local->mdev));
unregister_netdevice(local->mdev); unregister_netdevice(local->mdev);
local->mdev = NULL;
fail_dev: fail_dev:
rtnl_unlock(); rtnl_unlock();
sta_info_stop(local); sta_info_stop(local);
...@@ -1773,8 +1774,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw) ...@@ -1773,8 +1774,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
debugfs_hw_del(local); debugfs_hw_del(local);
destroy_workqueue(local->hw.workqueue); destroy_workqueue(local->hw.workqueue);
fail_workqueue: fail_workqueue:
if (local->mdev != NULL) {
ieee80211_if_free(local->mdev); ieee80211_if_free(local->mdev);
local->mdev = NULL; local->mdev = NULL;
}
fail_mdev_alloc: fail_mdev_alloc:
wiphy_unregister(local->hw.wiphy); wiphy_unregister(local->hw.wiphy);
return result; return result;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* as published by the Free Software Foundation; either version * as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version. * 2 of the License, or (at your option) any later version.
* *
* Authors: Jamal Hadi Salim (2005) * Authors: Jamal Hadi Salim (2005-8)
* *
*/ */
...@@ -34,6 +34,7 @@ static struct tcf_hashinfo simp_hash_info = { ...@@ -34,6 +34,7 @@ static struct tcf_hashinfo simp_hash_info = {
.lock = &simp_lock, .lock = &simp_lock,
}; };
#define SIMP_MAX_DATA 32
static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res) static int tcf_simp(struct sk_buff *skb, struct tc_action *a, struct tcf_result *res)
{ {
struct tcf_defact *d = a->priv; struct tcf_defact *d = a->priv;
...@@ -69,23 +70,28 @@ static int tcf_simp_release(struct tcf_defact *d, int bind) ...@@ -69,23 +70,28 @@ static int tcf_simp_release(struct tcf_defact *d, int bind)
return ret; return ret;
} }
static int alloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) static int alloc_defdata(struct tcf_defact *d, char *defdata)
{ {
d->tcfd_defdata = kmemdup(defdata, datalen, GFP_KERNEL); d->tcfd_defdata = kstrndup(defdata, SIMP_MAX_DATA, GFP_KERNEL);
if (unlikely(!d->tcfd_defdata)) if (unlikely(!d->tcfd_defdata))
return -ENOMEM; return -ENOMEM;
d->tcfd_datalen = datalen;
return 0; return 0;
} }
static int realloc_defdata(struct tcf_defact *d, u32 datalen, void *defdata) static void reset_policy(struct tcf_defact *d, char *defdata,
struct tc_defact *p)
{ {
kfree(d->tcfd_defdata); spin_lock_bh(&d->tcf_lock);
return alloc_defdata(d, datalen, defdata); d->tcf_action = p->action;
memset(d->tcfd_defdata, 0, SIMP_MAX_DATA);
strlcpy(d->tcfd_defdata, defdata, SIMP_MAX_DATA);
spin_unlock_bh(&d->tcf_lock);
} }
static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = { static const struct nla_policy simple_policy[TCA_DEF_MAX + 1] = {
[TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) }, [TCA_DEF_PARMS] = { .len = sizeof(struct tc_defact) },
[TCA_DEF_DATA] = { .type = NLA_STRING, .len = SIMP_MAX_DATA },
}; };
static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
...@@ -95,28 +101,24 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, ...@@ -95,28 +101,24 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
struct tc_defact *parm; struct tc_defact *parm;
struct tcf_defact *d; struct tcf_defact *d;
struct tcf_common *pc; struct tcf_common *pc;
void *defdata; char *defdata;
u32 datalen = 0;
int ret = 0, err; int ret = 0, err;
if (nla == NULL) if (nla == NULL)
return -EINVAL; return -EINVAL;
err = nla_parse_nested(tb, TCA_DEF_MAX, nla, NULL); err = nla_parse_nested(tb, TCA_DEF_MAX, nla, simple_policy);
if (err < 0) if (err < 0)
return err; return err;
if (tb[TCA_DEF_PARMS] == NULL) if (tb[TCA_DEF_PARMS] == NULL)
return -EINVAL; return -EINVAL;
parm = nla_data(tb[TCA_DEF_PARMS]); if (tb[TCA_DEF_DATA] == NULL)
defdata = nla_data(tb[TCA_DEF_DATA]);
if (defdata == NULL)
return -EINVAL; return -EINVAL;
datalen = nla_len(tb[TCA_DEF_DATA]); parm = nla_data(tb[TCA_DEF_PARMS]);
if (datalen == 0) defdata = nla_data(tb[TCA_DEF_DATA]);
return -EINVAL;
pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info); pc = tcf_hash_check(parm->index, a, bind, &simp_hash_info);
if (!pc) { if (!pc) {
...@@ -126,11 +128,12 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, ...@@ -126,11 +128,12 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
return -ENOMEM; return -ENOMEM;
d = to_defact(pc); d = to_defact(pc);
ret = alloc_defdata(d, datalen, defdata); ret = alloc_defdata(d, defdata);
if (ret < 0) { if (ret < 0) {
kfree(pc); kfree(pc);
return ret; return ret;
} }
d->tcf_action = parm->action;
ret = ACT_P_CREATED; ret = ACT_P_CREATED;
} else { } else {
d = to_defact(pc); d = to_defact(pc);
...@@ -138,13 +141,9 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, ...@@ -138,13 +141,9 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est,
tcf_simp_release(d, bind); tcf_simp_release(d, bind);
return -EEXIST; return -EEXIST;
} }
realloc_defdata(d, datalen, defdata); reset_policy(d, defdata, parm);
} }
spin_lock_bh(&d->tcf_lock);
d->tcf_action = parm->action;
spin_unlock_bh(&d->tcf_lock);
if (ret == ACT_P_CREATED) if (ret == ACT_P_CREATED)
tcf_hash_insert(pc, &simp_hash_info); tcf_hash_insert(pc, &simp_hash_info);
return ret; return ret;
...@@ -172,7 +171,7 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a, ...@@ -172,7 +171,7 @@ static inline int tcf_simp_dump(struct sk_buff *skb, struct tc_action *a,
opt.bindcnt = d->tcf_bindcnt - bind; opt.bindcnt = d->tcf_bindcnt - bind;
opt.action = d->tcf_action; opt.action = d->tcf_action;
NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt); NLA_PUT(skb, TCA_DEF_PARMS, sizeof(opt), &opt);
NLA_PUT(skb, TCA_DEF_DATA, d->tcfd_datalen, d->tcfd_defdata); NLA_PUT_STRING(skb, TCA_DEF_DATA, d->tcfd_defdata);
t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install); t.install = jiffies_to_clock_t(jiffies - d->tcf_tm.install);
t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse); t.lastuse = jiffies_to_clock_t(jiffies - d->tcf_tm.lastuse);
t.expires = jiffies_to_clock_t(d->tcf_tm.expires); t.expires = jiffies_to_clock_t(d->tcf_tm.expires);
......
...@@ -1197,12 +1197,16 @@ static inline int htb_parent_last_child(struct htb_class *cl) ...@@ -1197,12 +1197,16 @@ static inline int htb_parent_last_child(struct htb_class *cl)
return 1; return 1;
} }
static void htb_parent_to_leaf(struct htb_class *cl, struct Qdisc *new_q) static void htb_parent_to_leaf(struct htb_sched *q, struct htb_class *cl,
struct Qdisc *new_q)
{ {
struct htb_class *parent = cl->parent; struct htb_class *parent = cl->parent;
BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity); BUG_TRAP(!cl->level && cl->un.leaf.q && !cl->prio_activity);
if (parent->cmode != HTB_CAN_SEND)
htb_safe_rb_erase(&parent->pq_node, q->wait_pq + parent->level);
parent->level = 0; parent->level = 0;
memset(&parent->un.inner, 0, sizeof(parent->un.inner)); memset(&parent->un.inner, 0, sizeof(parent->un.inner));
INIT_LIST_HEAD(&parent->un.leaf.drop_list); INIT_LIST_HEAD(&parent->un.leaf.drop_list);
...@@ -1300,7 +1304,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg) ...@@ -1300,7 +1304,7 @@ static int htb_delete(struct Qdisc *sch, unsigned long arg)
htb_deactivate(q, cl); htb_deactivate(q, cl);
if (last_child) if (last_child)
htb_parent_to_leaf(cl, new_q); htb_parent_to_leaf(q, cl, new_q);
if (--cl->refcnt == 0) if (--cl->refcnt == 0)
htb_destroy_class(sch, cl); htb_destroy_class(sch, cl);
......
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