Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
* 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6: [NET]: Fix race condition about network device name allocation. [IPV4]: icmp: fix crash with sysctl_icmp_errors_use_inbound_ifaddr [NETFILTER]: nf_conntrack_ipv4: fix incorrect #ifdef config name [NETFILTER]: nf_conntrack: fix use-after-free in helper destroy callback invocation [IPSEC] pfkey: Load specific algorithm in pfkey_add rather than all [TCP] FRTO: Prevent state inconsistency in corner cases [TCP] FRTO: Add missing ECN CWR sending to one of the responses [NET]: Fix net/core/skbuff.c gcc-3.2.3 compilation error [RFKILL]: Fix check for correct rfkill allocation [IPV6]: Add ip6_tunnel.h to headers_install
This commit is contained in:
commit
6044ab324c
|
@ -239,6 +239,7 @@ unifdef-y += ipc.h
|
||||||
unifdef-y += ipmi.h
|
unifdef-y += ipmi.h
|
||||||
unifdef-y += ipv6.h
|
unifdef-y += ipv6.h
|
||||||
unifdef-y += ipv6_route.h
|
unifdef-y += ipv6_route.h
|
||||||
|
unifdef-y += ip6_tunnel.h
|
||||||
unifdef-y += isdn.h
|
unifdef-y += isdn.h
|
||||||
unifdef-y += isdnif.h
|
unifdef-y += isdnif.h
|
||||||
unifdef-y += isdn_divertif.h
|
unifdef-y += isdn_divertif.h
|
||||||
|
|
|
@ -3314,7 +3314,6 @@ void netdev_run_todo(void)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
netdev_unregister_sysfs(dev);
|
|
||||||
dev->reg_state = NETREG_UNREGISTERED;
|
dev->reg_state = NETREG_UNREGISTERED;
|
||||||
|
|
||||||
netdev_wait_allrefs(dev);
|
netdev_wait_allrefs(dev);
|
||||||
|
@ -3325,11 +3324,11 @@ void netdev_run_todo(void)
|
||||||
BUG_TRAP(!dev->ip6_ptr);
|
BUG_TRAP(!dev->ip6_ptr);
|
||||||
BUG_TRAP(!dev->dn_ptr);
|
BUG_TRAP(!dev->dn_ptr);
|
||||||
|
|
||||||
/* It must be the very last action,
|
|
||||||
* after this 'dev' may point to freed up memory.
|
|
||||||
*/
|
|
||||||
if (dev->destructor)
|
if (dev->destructor)
|
||||||
dev->destructor(dev);
|
dev->destructor(dev);
|
||||||
|
|
||||||
|
/* Free network device */
|
||||||
|
kobject_put(&dev->dev.kobj);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -3480,6 +3479,9 @@ void unregister_netdevice(struct net_device *dev)
|
||||||
/* Notifier chain MUST detach us from master device. */
|
/* Notifier chain MUST detach us from master device. */
|
||||||
BUG_TRAP(!dev->master);
|
BUG_TRAP(!dev->master);
|
||||||
|
|
||||||
|
/* Remove entries from sysfs */
|
||||||
|
netdev_unregister_sysfs(dev);
|
||||||
|
|
||||||
/* Finish processing unregister after unlock */
|
/* Finish processing unregister after unlock */
|
||||||
net_set_todo(dev);
|
net_set_todo(dev);
|
||||||
|
|
||||||
|
|
|
@ -456,9 +456,15 @@ static struct class net_class = {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Delete sysfs entries but hold kobject reference until after all
|
||||||
|
* netdev references are gone.
|
||||||
|
*/
|
||||||
void netdev_unregister_sysfs(struct net_device * net)
|
void netdev_unregister_sysfs(struct net_device * net)
|
||||||
{
|
{
|
||||||
device_del(&(net->dev));
|
struct device *dev = &(net->dev);
|
||||||
|
|
||||||
|
kobject_get(&dev->kobj);
|
||||||
|
device_del(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create sysfs entries for network device. */
|
/* Create sysfs entries for network device. */
|
||||||
|
|
|
@ -644,11 +644,10 @@ int pskb_expand_head(struct sk_buff *skb, int nhead, int ntail,
|
||||||
|
|
||||||
/* Copy only real data... and, alas, header. This should be
|
/* Copy only real data... and, alas, header. This should be
|
||||||
* optimized for the cases when header is void. */
|
* optimized for the cases when header is void. */
|
||||||
memcpy(data + nhead, skb->head,
|
|
||||||
#ifdef NET_SKBUFF_DATA_USES_OFFSET
|
#ifdef NET_SKBUFF_DATA_USES_OFFSET
|
||||||
skb->tail);
|
memcpy(data + nhead, skb->head, skb->tail);
|
||||||
#else
|
#else
|
||||||
skb->tail - skb->head);
|
memcpy(data + nhead, skb->head, skb->tail - skb->head);
|
||||||
#endif
|
#endif
|
||||||
memcpy(data + size, skb_end_pointer(skb),
|
memcpy(data + size, skb_end_pointer(skb),
|
||||||
sizeof(struct skb_shared_info));
|
sizeof(struct skb_shared_info));
|
||||||
|
|
|
@ -514,7 +514,10 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
|
||||||
|
|
||||||
saddr = iph->daddr;
|
saddr = iph->daddr;
|
||||||
if (!(rt->rt_flags & RTCF_LOCAL)) {
|
if (!(rt->rt_flags & RTCF_LOCAL)) {
|
||||||
if (sysctl_icmp_errors_use_inbound_ifaddr)
|
/* This is broken, skb_in->dev points to the outgoing device
|
||||||
|
* after the packet passes through ip_output().
|
||||||
|
*/
|
||||||
|
if (skb_in->dev && sysctl_icmp_errors_use_inbound_ifaddr)
|
||||||
saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
|
saddr = inet_select_addr(skb_in->dev, 0, RT_SCOPE_LINK);
|
||||||
else
|
else
|
||||||
saddr = 0;
|
saddr = 0;
|
||||||
|
|
|
@ -154,12 +154,10 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
|
||||||
const struct net_device *out,
|
const struct net_device *out,
|
||||||
int (*okfn)(struct sk_buff *))
|
int (*okfn)(struct sk_buff *))
|
||||||
{
|
{
|
||||||
#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
|
|
||||||
/* Previously seen (loopback)? Ignore. Do this before
|
/* Previously seen (loopback)? Ignore. Do this before
|
||||||
fragment check. */
|
fragment check. */
|
||||||
if ((*pskb)->nfct)
|
if ((*pskb)->nfct)
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Gather fragments. */
|
/* Gather fragments. */
|
||||||
if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
|
if (ip_hdr(*pskb)->frag_off & htons(IP_MF | IP_OFFSET)) {
|
||||||
|
|
|
@ -1501,6 +1501,8 @@ void tcp_enter_loss(struct sock *sk, int how)
|
||||||
tcp_set_ca_state(sk, TCP_CA_Loss);
|
tcp_set_ca_state(sk, TCP_CA_Loss);
|
||||||
tp->high_seq = tp->snd_nxt;
|
tp->high_seq = tp->snd_nxt;
|
||||||
TCP_ECN_queue_cwr(tp);
|
TCP_ECN_queue_cwr(tp);
|
||||||
|
/* Abort FRTO algorithm if one is in progress */
|
||||||
|
tp->frto_counter = 0;
|
||||||
|
|
||||||
clear_all_retrans_hints(tp);
|
clear_all_retrans_hints(tp);
|
||||||
}
|
}
|
||||||
|
@ -2608,6 +2610,7 @@ static void tcp_conservative_spur_to_response(struct tcp_sock *tp)
|
||||||
{
|
{
|
||||||
tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
|
tp->snd_cwnd = min(tp->snd_cwnd, tp->snd_ssthresh);
|
||||||
tp->snd_cwnd_cnt = 0;
|
tp->snd_cwnd_cnt = 0;
|
||||||
|
TCP_ECN_queue_cwr(tp);
|
||||||
tcp_moderate_cwnd(tp);
|
tcp_moderate_cwnd(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1448,8 +1448,6 @@ static int pfkey_add(struct sock *sk, struct sk_buff *skb, struct sadb_msg *hdr,
|
||||||
int err;
|
int err;
|
||||||
struct km_event c;
|
struct km_event c;
|
||||||
|
|
||||||
xfrm_probe_algs();
|
|
||||||
|
|
||||||
x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
|
x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
|
||||||
if (IS_ERR(x))
|
if (IS_ERR(x))
|
||||||
return PTR_ERR(x);
|
return PTR_ERR(x);
|
||||||
|
|
|
@ -298,7 +298,6 @@ static void
|
||||||
destroy_conntrack(struct nf_conntrack *nfct)
|
destroy_conntrack(struct nf_conntrack *nfct)
|
||||||
{
|
{
|
||||||
struct nf_conn *ct = (struct nf_conn *)nfct;
|
struct nf_conn *ct = (struct nf_conn *)nfct;
|
||||||
struct nf_conn_help *help = nfct_help(ct);
|
|
||||||
struct nf_conntrack_l4proto *l4proto;
|
struct nf_conntrack_l4proto *l4proto;
|
||||||
typeof(nf_conntrack_destroyed) destroyed;
|
typeof(nf_conntrack_destroyed) destroyed;
|
||||||
|
|
||||||
|
@ -309,9 +308,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
|
||||||
nf_conntrack_event(IPCT_DESTROY, ct);
|
nf_conntrack_event(IPCT_DESTROY, ct);
|
||||||
set_bit(IPS_DYING_BIT, &ct->status);
|
set_bit(IPS_DYING_BIT, &ct->status);
|
||||||
|
|
||||||
if (help && help->helper && help->helper->destroy)
|
|
||||||
help->helper->destroy(ct);
|
|
||||||
|
|
||||||
/* To make sure we don't get any weird locking issues here:
|
/* To make sure we don't get any weird locking issues here:
|
||||||
* destroy_conntrack() MUST NOT be called with a write lock
|
* destroy_conntrack() MUST NOT be called with a write lock
|
||||||
* to nf_conntrack_lock!!! -HW */
|
* to nf_conntrack_lock!!! -HW */
|
||||||
|
@ -353,6 +349,10 @@ destroy_conntrack(struct nf_conntrack *nfct)
|
||||||
static void death_by_timeout(unsigned long ul_conntrack)
|
static void death_by_timeout(unsigned long ul_conntrack)
|
||||||
{
|
{
|
||||||
struct nf_conn *ct = (void *)ul_conntrack;
|
struct nf_conn *ct = (void *)ul_conntrack;
|
||||||
|
struct nf_conn_help *help = nfct_help(ct);
|
||||||
|
|
||||||
|
if (help && help->helper && help->helper->destroy)
|
||||||
|
help->helper->destroy(ct);
|
||||||
|
|
||||||
write_lock_bh(&nf_conntrack_lock);
|
write_lock_bh(&nf_conntrack_lock);
|
||||||
/* Inside lock so preempt is disabled on module removal path.
|
/* Inside lock so preempt is disabled on module removal path.
|
||||||
|
|
|
@ -296,7 +296,7 @@ struct rfkill *rfkill_allocate(struct device *parent, enum rfkill_type type)
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
|
||||||
rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
|
rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
|
||||||
if (rfkill)
|
if (!rfkill)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
mutex_init(&rfkill->mutex);
|
mutex_init(&rfkill->mutex);
|
||||||
|
|
|
@ -347,67 +347,44 @@ static inline int calg_entries(void)
|
||||||
return ARRAY_SIZE(calg_list);
|
return ARRAY_SIZE(calg_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Todo: generic iterators */
|
struct xfrm_algo_list {
|
||||||
struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
|
struct xfrm_algo_desc *algs;
|
||||||
{
|
int entries;
|
||||||
int i;
|
u32 type;
|
||||||
|
u32 mask;
|
||||||
for (i = 0; i < aalg_entries(); i++) {
|
};
|
||||||
if (aalg_list[i].desc.sadb_alg_id == alg_id) {
|
|
||||||
if (aalg_list[i].available)
|
static const struct xfrm_algo_list xfrm_aalg_list = {
|
||||||
return &aalg_list[i];
|
.algs = aalg_list,
|
||||||
else
|
.entries = ARRAY_SIZE(aalg_list),
|
||||||
break;
|
.type = CRYPTO_ALG_TYPE_HASH,
|
||||||
}
|
.mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC,
|
||||||
}
|
};
|
||||||
return NULL;
|
|
||||||
}
|
static const struct xfrm_algo_list xfrm_ealg_list = {
|
||||||
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
|
.algs = ealg_list,
|
||||||
|
.entries = ARRAY_SIZE(ealg_list),
|
||||||
struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
|
.type = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||||
{
|
.mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
|
||||||
int i;
|
};
|
||||||
|
|
||||||
for (i = 0; i < ealg_entries(); i++) {
|
static const struct xfrm_algo_list xfrm_calg_list = {
|
||||||
if (ealg_list[i].desc.sadb_alg_id == alg_id) {
|
.algs = calg_list,
|
||||||
if (ealg_list[i].available)
|
.entries = ARRAY_SIZE(calg_list),
|
||||||
return &ealg_list[i];
|
.type = CRYPTO_ALG_TYPE_COMPRESS,
|
||||||
else
|
.mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
|
||||||
break;
|
};
|
||||||
}
|
|
||||||
}
|
static struct xfrm_algo_desc *xfrm_find_algo(
|
||||||
return NULL;
|
const struct xfrm_algo_list *algo_list,
|
||||||
}
|
int match(const struct xfrm_algo_desc *entry, const void *data),
|
||||||
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
|
const void *data, int probe)
|
||||||
|
|
||||||
struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < calg_entries(); i++) {
|
|
||||||
if (calg_list[i].desc.sadb_alg_id == alg_id) {
|
|
||||||
if (calg_list[i].available)
|
|
||||||
return &calg_list[i];
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
|
|
||||||
|
|
||||||
static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
|
|
||||||
int entries, u32 type, u32 mask,
|
|
||||||
char *name, int probe)
|
|
||||||
{
|
{
|
||||||
|
struct xfrm_algo_desc *list = algo_list->algs;
|
||||||
int i, status;
|
int i, status;
|
||||||
|
|
||||||
if (!name)
|
for (i = 0; i < algo_list->entries; i++) {
|
||||||
return NULL;
|
if (!match(list + i, data))
|
||||||
|
|
||||||
for (i = 0; i < entries; i++) {
|
|
||||||
if (strcmp(name, list[i].name) &&
|
|
||||||
(!list[i].compat || strcmp(name, list[i].compat)))
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (list[i].available)
|
if (list[i].available)
|
||||||
|
@ -416,8 +393,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
|
||||||
if (!probe)
|
if (!probe)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
status = crypto_has_alg(list[i].name, type,
|
status = crypto_has_alg(list[i].name, algo_list->type,
|
||||||
mask | CRYPTO_ALG_ASYNC);
|
algo_list->mask);
|
||||||
if (!status)
|
if (!status)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -427,27 +404,60 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int xfrm_alg_id_match(const struct xfrm_algo_desc *entry,
|
||||||
|
const void *data)
|
||||||
|
{
|
||||||
|
return entry->desc.sadb_alg_id == (int)data;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
|
||||||
|
{
|
||||||
|
return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_id_match,
|
||||||
|
(void *)alg_id, 1);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
|
||||||
|
|
||||||
|
struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
|
||||||
|
{
|
||||||
|
return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_id_match,
|
||||||
|
(void *)alg_id, 1);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
|
||||||
|
|
||||||
|
struct xfrm_algo_desc *xfrm_calg_get_byid(int alg_id)
|
||||||
|
{
|
||||||
|
return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_id_match,
|
||||||
|
(void *)alg_id, 1);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(xfrm_calg_get_byid);
|
||||||
|
|
||||||
|
static int xfrm_alg_name_match(const struct xfrm_algo_desc *entry,
|
||||||
|
const void *data)
|
||||||
|
{
|
||||||
|
const char *name = data;
|
||||||
|
|
||||||
|
return name && (!strcmp(name, entry->name) ||
|
||||||
|
(entry->compat && !strcmp(name, entry->compat)));
|
||||||
|
}
|
||||||
|
|
||||||
struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe)
|
struct xfrm_algo_desc *xfrm_aalg_get_byname(char *name, int probe)
|
||||||
{
|
{
|
||||||
return xfrm_get_byname(aalg_list, aalg_entries(),
|
return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
|
||||||
CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK,
|
probe);
|
||||||
name, probe);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
|
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
|
||||||
|
|
||||||
struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
|
struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
|
||||||
{
|
{
|
||||||
return xfrm_get_byname(ealg_list, ealg_entries(),
|
return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
|
||||||
CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK,
|
probe);
|
||||||
name, probe);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
|
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
|
||||||
|
|
||||||
struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
|
struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
|
||||||
{
|
{
|
||||||
return xfrm_get_byname(calg_list, calg_entries(),
|
return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
|
||||||
CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK,
|
probe);
|
||||||
name, probe);
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
|
EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue