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 += ipv6.h
|
||||
unifdef-y += ipv6_route.h
|
||||
unifdef-y += ip6_tunnel.h
|
||||
unifdef-y += isdn.h
|
||||
unifdef-y += isdnif.h
|
||||
unifdef-y += isdn_divertif.h
|
||||
|
|
|
@ -3314,7 +3314,6 @@ void netdev_run_todo(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
netdev_unregister_sysfs(dev);
|
||||
dev->reg_state = NETREG_UNREGISTERED;
|
||||
|
||||
netdev_wait_allrefs(dev);
|
||||
|
@ -3325,11 +3324,11 @@ void netdev_run_todo(void)
|
|||
BUG_TRAP(!dev->ip6_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)
|
||||
dev->destructor(dev);
|
||||
|
||||
/* Free network device */
|
||||
kobject_put(&dev->dev.kobj);
|
||||
}
|
||||
|
||||
out:
|
||||
|
@ -3480,6 +3479,9 @@ void unregister_netdevice(struct net_device *dev)
|
|||
/* Notifier chain MUST detach us from master device. */
|
||||
BUG_TRAP(!dev->master);
|
||||
|
||||
/* Remove entries from sysfs */
|
||||
netdev_unregister_sysfs(dev);
|
||||
|
||||
/* Finish processing unregister after unlock */
|
||||
net_set_todo(dev);
|
||||
|
||||
|
|
|
@ -456,9 +456,15 @@ static struct class net_class = {
|
|||
#endif
|
||||
};
|
||||
|
||||
/* Delete sysfs entries but hold kobject reference until after all
|
||||
* netdev references are gone.
|
||||
*/
|
||||
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. */
|
||||
|
|
|
@ -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
|
||||
* optimized for the cases when header is void. */
|
||||
memcpy(data + nhead, skb->head,
|
||||
#ifdef NET_SKBUFF_DATA_USES_OFFSET
|
||||
skb->tail);
|
||||
memcpy(data + nhead, skb->head, skb->tail);
|
||||
#else
|
||||
skb->tail - skb->head);
|
||||
memcpy(data + nhead, skb->head, skb->tail - skb->head);
|
||||
#endif
|
||||
memcpy(data + size, skb_end_pointer(skb),
|
||||
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;
|
||||
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);
|
||||
else
|
||||
saddr = 0;
|
||||
|
|
|
@ -154,12 +154,10 @@ static unsigned int ipv4_conntrack_defrag(unsigned int hooknum,
|
|||
const struct net_device *out,
|
||||
int (*okfn)(struct sk_buff *))
|
||||
{
|
||||
#if !defined(CONFIG_IP_NF_NAT) && !defined(CONFIG_IP_NF_NAT_MODULE)
|
||||
/* Previously seen (loopback)? Ignore. Do this before
|
||||
fragment check. */
|
||||
if ((*pskb)->nfct)
|
||||
return NF_ACCEPT;
|
||||
#endif
|
||||
|
||||
/* Gather fragments. */
|
||||
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);
|
||||
tp->high_seq = tp->snd_nxt;
|
||||
TCP_ECN_queue_cwr(tp);
|
||||
/* Abort FRTO algorithm if one is in progress */
|
||||
tp->frto_counter = 0;
|
||||
|
||||
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_cnt = 0;
|
||||
TCP_ECN_queue_cwr(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;
|
||||
struct km_event c;
|
||||
|
||||
xfrm_probe_algs();
|
||||
|
||||
x = pfkey_msg2xfrm_state(hdr, ext_hdrs);
|
||||
if (IS_ERR(x))
|
||||
return PTR_ERR(x);
|
||||
|
|
|
@ -298,7 +298,6 @@ static void
|
|||
destroy_conntrack(struct nf_conntrack *nfct)
|
||||
{
|
||||
struct nf_conn *ct = (struct nf_conn *)nfct;
|
||||
struct nf_conn_help *help = nfct_help(ct);
|
||||
struct nf_conntrack_l4proto *l4proto;
|
||||
typeof(nf_conntrack_destroyed) destroyed;
|
||||
|
||||
|
@ -309,9 +308,6 @@ destroy_conntrack(struct nf_conntrack *nfct)
|
|||
nf_conntrack_event(IPCT_DESTROY, ct);
|
||||
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:
|
||||
* destroy_conntrack() MUST NOT be called with a write lock
|
||||
* to nf_conntrack_lock!!! -HW */
|
||||
|
@ -353,6 +349,10 @@ destroy_conntrack(struct nf_conntrack *nfct)
|
|||
static void death_by_timeout(unsigned long 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);
|
||||
/* 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;
|
||||
|
||||
rfkill = kzalloc(sizeof(struct rfkill), GFP_KERNEL);
|
||||
if (rfkill)
|
||||
if (!rfkill)
|
||||
return NULL;
|
||||
|
||||
mutex_init(&rfkill->mutex);
|
||||
|
|
|
@ -347,67 +347,44 @@ static inline int calg_entries(void)
|
|||
return ARRAY_SIZE(calg_list);
|
||||
}
|
||||
|
||||
/* Todo: generic iterators */
|
||||
struct xfrm_algo_desc *xfrm_aalg_get_byid(int alg_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < aalg_entries(); i++) {
|
||||
if (aalg_list[i].desc.sadb_alg_id == alg_id) {
|
||||
if (aalg_list[i].available)
|
||||
return &aalg_list[i];
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byid);
|
||||
|
||||
struct xfrm_algo_desc *xfrm_ealg_get_byid(int alg_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ealg_entries(); i++) {
|
||||
if (ealg_list[i].desc.sadb_alg_id == alg_id) {
|
||||
if (ealg_list[i].available)
|
||||
return &ealg_list[i];
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byid);
|
||||
|
||||
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_list {
|
||||
struct xfrm_algo_desc *algs;
|
||||
int entries;
|
||||
u32 type;
|
||||
u32 mask;
|
||||
};
|
||||
|
||||
static const struct xfrm_algo_list xfrm_aalg_list = {
|
||||
.algs = aalg_list,
|
||||
.entries = ARRAY_SIZE(aalg_list),
|
||||
.type = CRYPTO_ALG_TYPE_HASH,
|
||||
.mask = CRYPTO_ALG_TYPE_HASH_MASK | CRYPTO_ALG_ASYNC,
|
||||
};
|
||||
|
||||
static const struct xfrm_algo_list xfrm_ealg_list = {
|
||||
.algs = ealg_list,
|
||||
.entries = ARRAY_SIZE(ealg_list),
|
||||
.type = CRYPTO_ALG_TYPE_BLKCIPHER,
|
||||
.mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
|
||||
};
|
||||
|
||||
static const struct xfrm_algo_list xfrm_calg_list = {
|
||||
.algs = calg_list,
|
||||
.entries = ARRAY_SIZE(calg_list),
|
||||
.type = CRYPTO_ALG_TYPE_COMPRESS,
|
||||
.mask = CRYPTO_ALG_TYPE_MASK | CRYPTO_ALG_ASYNC,
|
||||
};
|
||||
|
||||
static struct xfrm_algo_desc *xfrm_find_algo(
|
||||
const struct xfrm_algo_list *algo_list,
|
||||
int match(const struct xfrm_algo_desc *entry, const void *data),
|
||||
const void *data, int probe)
|
||||
{
|
||||
struct xfrm_algo_desc *list = algo_list->algs;
|
||||
int i, status;
|
||||
|
||||
if (!name)
|
||||
return NULL;
|
||||
|
||||
for (i = 0; i < entries; i++) {
|
||||
if (strcmp(name, list[i].name) &&
|
||||
(!list[i].compat || strcmp(name, list[i].compat)))
|
||||
for (i = 0; i < algo_list->entries; i++) {
|
||||
if (!match(list + i, data))
|
||||
continue;
|
||||
|
||||
if (list[i].available)
|
||||
|
@ -416,8 +393,8 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
|
|||
if (!probe)
|
||||
break;
|
||||
|
||||
status = crypto_has_alg(list[i].name, type,
|
||||
mask | CRYPTO_ALG_ASYNC);
|
||||
status = crypto_has_alg(list[i].name, algo_list->type,
|
||||
algo_list->mask);
|
||||
if (!status)
|
||||
break;
|
||||
|
||||
|
@ -427,27 +404,60 @@ static struct xfrm_algo_desc *xfrm_get_byname(struct xfrm_algo_desc *list,
|
|||
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)
|
||||
{
|
||||
return xfrm_get_byname(aalg_list, aalg_entries(),
|
||||
CRYPTO_ALG_TYPE_HASH, CRYPTO_ALG_TYPE_HASH_MASK,
|
||||
name, probe);
|
||||
return xfrm_find_algo(&xfrm_aalg_list, xfrm_alg_name_match, name,
|
||||
probe);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xfrm_aalg_get_byname);
|
||||
|
||||
struct xfrm_algo_desc *xfrm_ealg_get_byname(char *name, int probe)
|
||||
{
|
||||
return xfrm_get_byname(ealg_list, ealg_entries(),
|
||||
CRYPTO_ALG_TYPE_BLKCIPHER, CRYPTO_ALG_TYPE_MASK,
|
||||
name, probe);
|
||||
return xfrm_find_algo(&xfrm_ealg_list, xfrm_alg_name_match, name,
|
||||
probe);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xfrm_ealg_get_byname);
|
||||
|
||||
struct xfrm_algo_desc *xfrm_calg_get_byname(char *name, int probe)
|
||||
{
|
||||
return xfrm_get_byname(calg_list, calg_entries(),
|
||||
CRYPTO_ALG_TYPE_COMPRESS, CRYPTO_ALG_TYPE_MASK,
|
||||
name, probe);
|
||||
return xfrm_find_algo(&xfrm_calg_list, xfrm_alg_name_match, name,
|
||||
probe);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(xfrm_calg_get_byname);
|
||||
|
||||
|
|
Loading…
Reference in a new issue