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: [ICMP]: ICMP_MIB_OUTMSGS increment duplicated [IPV6]: RFC 2011 compatibility broken [IPV6]: ICMP6_MIB_OUTMSGS increment duplicated [NET]: rtnl_link: fix use-after-free [AF_KEY]: Fix skb leak on pfkey_send_migrate() error [ATM] atm/suni.c: Fix section mismatch. [ATM] atm/idt77105.c: Fix section mismatch. [IrDA]: af_irda memory leak fixes [NEIGH]: Revert 'Fix race between neigh_parms_release and neightbl_fill_parms' [NETFILTER]: bridge-netfilter: fix net_device refcnt leaks [IPV6] ROUTE: Make sending algorithm more friendly with RFC 4861. [IPV4] FIB_HASH : Avoid unecessary loop in fn_hash_dump_zone() [NET]: Fix interrupt semaphore corruption in Intel drivers. [IPV4] fib_trie: fix duplicated route issue [IPV4] fib_hash: fix duplicated route issue [IPV6]: Mischecked tw match in __inet6_check_established. rfkill: call rfkill_led_trigger_unregister() on error
This commit is contained in:
@ -357,7 +357,7 @@ static const struct atmphy_ops idt77105_ops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int __devinit idt77105_init(struct atm_dev *dev)
|
int idt77105_init(struct atm_dev *dev)
|
||||||
{
|
{
|
||||||
dev->phy = &idt77105_ops;
|
dev->phy = &idt77105_ops;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -289,7 +289,7 @@ static const struct atmphy_ops suni_ops = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int __devinit suni_init(struct atm_dev *dev)
|
int suni_init(struct atm_dev *dev)
|
||||||
{
|
{
|
||||||
unsigned char mri;
|
unsigned char mri;
|
||||||
|
|
||||||
|
@ -632,6 +632,7 @@ e1000_down(struct e1000_adapter *adapter)
|
|||||||
|
|
||||||
#ifdef CONFIG_E1000_NAPI
|
#ifdef CONFIG_E1000_NAPI
|
||||||
napi_disable(&adapter->napi);
|
napi_disable(&adapter->napi);
|
||||||
|
atomic_set(&adapter->irq_sem, 0);
|
||||||
#endif
|
#endif
|
||||||
e1000_irq_disable(adapter);
|
e1000_irq_disable(adapter);
|
||||||
|
|
||||||
|
@ -2183,6 +2183,7 @@ void e1000e_down(struct e1000_adapter *adapter)
|
|||||||
msleep(10);
|
msleep(10);
|
||||||
|
|
||||||
napi_disable(&adapter->napi);
|
napi_disable(&adapter->napi);
|
||||||
|
atomic_set(&adapter->irq_sem, 0);
|
||||||
e1000_irq_disable(adapter);
|
e1000_irq_disable(adapter);
|
||||||
|
|
||||||
del_timer_sync(&adapter->watchdog_timer);
|
del_timer_sync(&adapter->watchdog_timer);
|
||||||
|
@ -296,6 +296,11 @@ ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
|
|||||||
{
|
{
|
||||||
struct net_device *netdev = adapter->netdev;
|
struct net_device *netdev = adapter->netdev;
|
||||||
|
|
||||||
|
#ifdef CONFIG_IXGB_NAPI
|
||||||
|
napi_disable(&adapter->napi);
|
||||||
|
atomic_set(&adapter->irq_sem, 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
ixgb_irq_disable(adapter);
|
ixgb_irq_disable(adapter);
|
||||||
free_irq(adapter->pdev->irq, netdev);
|
free_irq(adapter->pdev->irq, netdev);
|
||||||
|
|
||||||
@ -304,9 +309,7 @@ ixgb_down(struct ixgb_adapter *adapter, boolean_t kill_watchdog)
|
|||||||
|
|
||||||
if(kill_watchdog)
|
if(kill_watchdog)
|
||||||
del_timer_sync(&adapter->watchdog_timer);
|
del_timer_sync(&adapter->watchdog_timer);
|
||||||
#ifdef CONFIG_IXGB_NAPI
|
|
||||||
napi_disable(&adapter->napi);
|
|
||||||
#endif
|
|
||||||
adapter->link_speed = 0;
|
adapter->link_speed = 0;
|
||||||
adapter->link_duplex = 0;
|
adapter->link_duplex = 0;
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
|
@ -1409,9 +1409,11 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
|
|||||||
IXGBE_WRITE_FLUSH(&adapter->hw);
|
IXGBE_WRITE_FLUSH(&adapter->hw);
|
||||||
msleep(10);
|
msleep(10);
|
||||||
|
|
||||||
|
napi_disable(&adapter->napi);
|
||||||
|
atomic_set(&adapter->irq_sem, 0);
|
||||||
|
|
||||||
ixgbe_irq_disable(adapter);
|
ixgbe_irq_disable(adapter);
|
||||||
|
|
||||||
napi_disable(&adapter->napi);
|
|
||||||
del_timer_sync(&adapter->watchdog_timer);
|
del_timer_sync(&adapter->watchdog_timer);
|
||||||
|
|
||||||
netif_carrier_off(netdev);
|
netif_carrier_off(netdev);
|
||||||
|
@ -459,19 +459,7 @@ static __init int veth_init(void)
|
|||||||
|
|
||||||
static __exit void veth_exit(void)
|
static __exit void veth_exit(void)
|
||||||
{
|
{
|
||||||
struct veth_priv *priv, *next;
|
rtnl_link_unregister(&veth_link_ops);
|
||||||
|
|
||||||
rtnl_lock();
|
|
||||||
/*
|
|
||||||
* cannot trust __rtnl_link_unregister() to unregister all
|
|
||||||
* devices, as each ->dellink call will remove two devices
|
|
||||||
* from the list at once.
|
|
||||||
*/
|
|
||||||
list_for_each_entry_safe(priv, next, &veth_list, list)
|
|
||||||
veth_dellink(priv->dev);
|
|
||||||
|
|
||||||
__rtnl_link_unregister(&veth_link_ops);
|
|
||||||
rtnl_unlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(veth_init);
|
module_init(veth_init);
|
||||||
|
@ -142,6 +142,23 @@ static inline struct nf_bridge_info *nf_bridge_alloc(struct sk_buff *skb)
|
|||||||
return skb->nf_bridge;
|
return skb->nf_bridge;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline struct nf_bridge_info *nf_bridge_unshare(struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
struct nf_bridge_info *nf_bridge = skb->nf_bridge;
|
||||||
|
|
||||||
|
if (atomic_read(&nf_bridge->use) > 1) {
|
||||||
|
struct nf_bridge_info *tmp = nf_bridge_alloc(skb);
|
||||||
|
|
||||||
|
if (tmp) {
|
||||||
|
memcpy(tmp, nf_bridge, sizeof(struct nf_bridge_info));
|
||||||
|
atomic_set(&tmp->use, 1);
|
||||||
|
nf_bridge_put(nf_bridge);
|
||||||
|
}
|
||||||
|
nf_bridge = tmp;
|
||||||
|
}
|
||||||
|
return nf_bridge;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void nf_bridge_push_encap_header(struct sk_buff *skb)
|
static inline void nf_bridge_push_encap_header(struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
unsigned int len = nf_bridge_encap_header_len(skb);
|
unsigned int len = nf_bridge_encap_header_len(skb);
|
||||||
@ -637,6 +654,11 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
|
|||||||
if (!skb->nf_bridge)
|
if (!skb->nf_bridge)
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
|
/* Need exclusive nf_bridge_info since we might have multiple
|
||||||
|
* different physoutdevs. */
|
||||||
|
if (!nf_bridge_unshare(skb))
|
||||||
|
return NF_DROP;
|
||||||
|
|
||||||
parent = bridge_parent(out);
|
parent = bridge_parent(out);
|
||||||
if (!parent)
|
if (!parent)
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
@ -718,6 +740,11 @@ static unsigned int br_nf_local_out(unsigned int hook, struct sk_buff *skb,
|
|||||||
if (!skb->nf_bridge)
|
if (!skb->nf_bridge)
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
|
||||||
|
/* Need exclusive nf_bridge_info since we might have multiple
|
||||||
|
* different physoutdevs. */
|
||||||
|
if (!nf_bridge_unshare(skb))
|
||||||
|
return NF_DROP;
|
||||||
|
|
||||||
nf_bridge = skb->nf_bridge;
|
nf_bridge = skb->nf_bridge;
|
||||||
if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
|
if (!(nf_bridge->mask & BRNF_BRIDGED_DNAT))
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
@ -1316,6 +1316,8 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
|
|||||||
*p = parms->next;
|
*p = parms->next;
|
||||||
parms->dead = 1;
|
parms->dead = 1;
|
||||||
write_unlock_bh(&tbl->lock);
|
write_unlock_bh(&tbl->lock);
|
||||||
|
if (parms->dev)
|
||||||
|
dev_put(parms->dev);
|
||||||
call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
|
call_rcu(&parms->rcu_head, neigh_rcu_free_parms);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1326,8 +1328,6 @@ void neigh_parms_release(struct neigh_table *tbl, struct neigh_parms *parms)
|
|||||||
|
|
||||||
void neigh_parms_destroy(struct neigh_parms *parms)
|
void neigh_parms_destroy(struct neigh_parms *parms)
|
||||||
{
|
{
|
||||||
if (parms->dev)
|
|
||||||
dev_put(parms->dev);
|
|
||||||
kfree(parms);
|
kfree(parms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,9 +308,12 @@ void __rtnl_link_unregister(struct rtnl_link_ops *ops)
|
|||||||
struct net *net;
|
struct net *net;
|
||||||
|
|
||||||
for_each_net(net) {
|
for_each_net(net) {
|
||||||
|
restart:
|
||||||
for_each_netdev_safe(net, dev, n) {
|
for_each_netdev_safe(net, dev, n) {
|
||||||
if (dev->rtnl_link_ops == ops)
|
if (dev->rtnl_link_ops == ops) {
|
||||||
ops->dellink(dev);
|
ops->dellink(dev);
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
list_del(&ops->list);
|
list_del(&ops->list);
|
||||||
|
@ -444,6 +444,9 @@ static int fn_hash_insert(struct fib_table *tb, struct fib_config *cfg)
|
|||||||
struct fib_info *fi_drop;
|
struct fib_info *fi_drop;
|
||||||
u8 state;
|
u8 state;
|
||||||
|
|
||||||
|
if (fi->fib_treeref > 1)
|
||||||
|
goto out;
|
||||||
|
|
||||||
write_lock_bh(&fib_hash_lock);
|
write_lock_bh(&fib_hash_lock);
|
||||||
fi_drop = fa->fa_info;
|
fi_drop = fa->fa_info;
|
||||||
fa->fa_info = fi;
|
fa->fa_info = fi;
|
||||||
@ -718,19 +721,18 @@ fn_hash_dump_zone(struct sk_buff *skb, struct netlink_callback *cb,
|
|||||||
{
|
{
|
||||||
int h, s_h;
|
int h, s_h;
|
||||||
|
|
||||||
|
if (fz->fz_hash == NULL)
|
||||||
|
return skb->len;
|
||||||
s_h = cb->args[3];
|
s_h = cb->args[3];
|
||||||
for (h=0; h < fz->fz_divisor; h++) {
|
for (h = s_h; h < fz->fz_divisor; h++) {
|
||||||
if (h < s_h) continue;
|
if (hlist_empty(&fz->fz_hash[h]))
|
||||||
if (h > s_h)
|
|
||||||
memset(&cb->args[4], 0,
|
|
||||||
sizeof(cb->args) - 4*sizeof(cb->args[0]));
|
|
||||||
if (fz->fz_hash == NULL ||
|
|
||||||
hlist_empty(&fz->fz_hash[h]))
|
|
||||||
continue;
|
continue;
|
||||||
if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h])<0) {
|
if (fn_hash_dump_bucket(skb, cb, tb, fz, &fz->fz_hash[h]) < 0) {
|
||||||
cb->args[3] = h;
|
cb->args[3] = h;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
memset(&cb->args[4], 0,
|
||||||
|
sizeof(cb->args) - 4*sizeof(cb->args[0]));
|
||||||
}
|
}
|
||||||
cb->args[3] = h;
|
cb->args[3] = h;
|
||||||
return skb->len;
|
return skb->len;
|
||||||
@ -746,14 +748,13 @@ static int fn_hash_dump(struct fib_table *tb, struct sk_buff *skb, struct netlin
|
|||||||
read_lock(&fib_hash_lock);
|
read_lock(&fib_hash_lock);
|
||||||
for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) {
|
for (fz = table->fn_zone_list, m=0; fz; fz = fz->fz_next, m++) {
|
||||||
if (m < s_m) continue;
|
if (m < s_m) continue;
|
||||||
if (m > s_m)
|
|
||||||
memset(&cb->args[3], 0,
|
|
||||||
sizeof(cb->args) - 3*sizeof(cb->args[0]));
|
|
||||||
if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) {
|
if (fn_hash_dump_zone(skb, cb, tb, fz) < 0) {
|
||||||
cb->args[2] = m;
|
cb->args[2] = m;
|
||||||
read_unlock(&fib_hash_lock);
|
read_unlock(&fib_hash_lock);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
memset(&cb->args[3], 0,
|
||||||
|
sizeof(cb->args) - 3*sizeof(cb->args[0]));
|
||||||
}
|
}
|
||||||
read_unlock(&fib_hash_lock);
|
read_unlock(&fib_hash_lock);
|
||||||
cb->args[2] = m;
|
cb->args[2] = m;
|
||||||
|
@ -1214,6 +1214,9 @@ static int fn_trie_insert(struct fib_table *tb, struct fib_config *cfg)
|
|||||||
struct fib_info *fi_drop;
|
struct fib_info *fi_drop;
|
||||||
u8 state;
|
u8 state;
|
||||||
|
|
||||||
|
if (fi->fib_treeref > 1)
|
||||||
|
goto out;
|
||||||
|
|
||||||
err = -ENOBUFS;
|
err = -ENOBUFS;
|
||||||
new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
|
new_fa = kmem_cache_alloc(fn_alias_kmem, GFP_KERNEL);
|
||||||
if (new_fa == NULL)
|
if (new_fa == NULL)
|
||||||
|
@ -540,7 +540,6 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
|
|||||||
icmp_param.data.icmph.checksum = 0;
|
icmp_param.data.icmph.checksum = 0;
|
||||||
icmp_param.skb = skb_in;
|
icmp_param.skb = skb_in;
|
||||||
icmp_param.offset = skb_network_offset(skb_in);
|
icmp_param.offset = skb_network_offset(skb_in);
|
||||||
icmp_out_count(icmp_param.data.icmph.type);
|
|
||||||
inet_sk(icmp_socket->sk)->tos = tos;
|
inet_sk(icmp_socket->sk)->tos = tos;
|
||||||
ipc.addr = iph->saddr;
|
ipc.addr = iph->saddr;
|
||||||
ipc.opt = &icmp_param.replyopts;
|
ipc.opt = &icmp_param.replyopts;
|
||||||
|
@ -458,8 +458,6 @@ void icmpv6_send(struct sk_buff *skb, int type, int code, __u32 info,
|
|||||||
}
|
}
|
||||||
err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
|
err = icmpv6_push_pending_frames(sk, &fl, &tmp_hdr, len + sizeof(struct icmp6hdr));
|
||||||
|
|
||||||
ICMP6_INC_STATS_BH(idev, ICMP6_MIB_OUTMSGS);
|
|
||||||
|
|
||||||
out_put:
|
out_put:
|
||||||
if (likely(idev != NULL))
|
if (likely(idev != NULL))
|
||||||
in6_dev_put(idev);
|
in6_dev_put(idev);
|
||||||
|
@ -193,7 +193,7 @@ static int __inet6_check_established(struct inet_timewait_death_row *death_row,
|
|||||||
sk2->sk_family == PF_INET6 &&
|
sk2->sk_family == PF_INET6 &&
|
||||||
ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) &&
|
ipv6_addr_equal(&tw6->tw_v6_daddr, saddr) &&
|
||||||
ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
|
ipv6_addr_equal(&tw6->tw_v6_rcv_saddr, daddr) &&
|
||||||
sk2->sk_bound_dev_if == sk->sk_bound_dev_if) {
|
(!sk2->sk_bound_dev_if || sk2->sk_bound_dev_if == dif)) {
|
||||||
if (twsk_unique(sk, sk2, twp))
|
if (twsk_unique(sk, sk2, twp))
|
||||||
goto unique;
|
goto unique;
|
||||||
else
|
else
|
||||||
|
@ -88,7 +88,7 @@ static char *icmp6type2name[256] = {
|
|||||||
[ICMPV6_PKT_TOOBIG] = "PktTooBigs",
|
[ICMPV6_PKT_TOOBIG] = "PktTooBigs",
|
||||||
[ICMPV6_TIME_EXCEED] = "TimeExcds",
|
[ICMPV6_TIME_EXCEED] = "TimeExcds",
|
||||||
[ICMPV6_PARAMPROB] = "ParmProblems",
|
[ICMPV6_PARAMPROB] = "ParmProblems",
|
||||||
[ICMPV6_ECHO_REQUEST] = "EchoRequest",
|
[ICMPV6_ECHO_REQUEST] = "Echos",
|
||||||
[ICMPV6_ECHO_REPLY] = "EchoReplies",
|
[ICMPV6_ECHO_REPLY] = "EchoReplies",
|
||||||
[ICMPV6_MGM_QUERY] = "GroupMembQueries",
|
[ICMPV6_MGM_QUERY] = "GroupMembQueries",
|
||||||
[ICMPV6_MGM_REPORT] = "GroupMembResponses",
|
[ICMPV6_MGM_REPORT] = "GroupMembResponses",
|
||||||
@ -98,7 +98,7 @@ static char *icmp6type2name[256] = {
|
|||||||
[NDISC_ROUTER_SOLICITATION] = "RouterSolicits",
|
[NDISC_ROUTER_SOLICITATION] = "RouterSolicits",
|
||||||
[NDISC_NEIGHBOUR_ADVERTISEMENT] = "NeighborAdvertisements",
|
[NDISC_NEIGHBOUR_ADVERTISEMENT] = "NeighborAdvertisements",
|
||||||
[NDISC_NEIGHBOUR_SOLICITATION] = "NeighborSolicits",
|
[NDISC_NEIGHBOUR_SOLICITATION] = "NeighborSolicits",
|
||||||
[NDISC_REDIRECT] = "NeighborRedirects",
|
[NDISC_REDIRECT] = "Redirects",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -329,7 +329,7 @@ static inline int rt6_check_dev(struct rt6_info *rt, int oif)
|
|||||||
static inline int rt6_check_neigh(struct rt6_info *rt)
|
static inline int rt6_check_neigh(struct rt6_info *rt)
|
||||||
{
|
{
|
||||||
struct neighbour *neigh = rt->rt6i_nexthop;
|
struct neighbour *neigh = rt->rt6i_nexthop;
|
||||||
int m = 0;
|
int m;
|
||||||
if (rt->rt6i_flags & RTF_NONEXTHOP ||
|
if (rt->rt6i_flags & RTF_NONEXTHOP ||
|
||||||
!(rt->rt6i_flags & RTF_GATEWAY))
|
!(rt->rt6i_flags & RTF_GATEWAY))
|
||||||
m = 1;
|
m = 1;
|
||||||
@ -337,10 +337,15 @@ static inline int rt6_check_neigh(struct rt6_info *rt)
|
|||||||
read_lock_bh(&neigh->lock);
|
read_lock_bh(&neigh->lock);
|
||||||
if (neigh->nud_state & NUD_VALID)
|
if (neigh->nud_state & NUD_VALID)
|
||||||
m = 2;
|
m = 2;
|
||||||
else if (!(neigh->nud_state & NUD_FAILED))
|
#ifdef CONFIG_IPV6_ROUTER_PREF
|
||||||
|
else if (neigh->nud_state & NUD_FAILED)
|
||||||
|
m = 0;
|
||||||
|
#endif
|
||||||
|
else
|
||||||
m = 1;
|
m = 1;
|
||||||
read_unlock_bh(&neigh->lock);
|
read_unlock_bh(&neigh->lock);
|
||||||
}
|
} else
|
||||||
|
m = 0;
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -802,12 +802,18 @@ static int irda_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_IRDA_ULTRA */
|
#endif /* CONFIG_IRDA_ULTRA */
|
||||||
|
|
||||||
|
self->ias_obj = irias_new_object(addr->sir_name, jiffies);
|
||||||
|
if (self->ias_obj == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name);
|
err = irda_open_tsap(self, addr->sir_lsap_sel, addr->sir_name);
|
||||||
if (err < 0)
|
if (err < 0) {
|
||||||
|
kfree(self->ias_obj->name);
|
||||||
|
kfree(self->ias_obj);
|
||||||
return err;
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
/* Register with LM-IAS */
|
/* Register with LM-IAS */
|
||||||
self->ias_obj = irias_new_object(addr->sir_name, jiffies);
|
|
||||||
irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel",
|
irias_add_integer_attrib(self->ias_obj, "IrDA:TinyTP:LsapSel",
|
||||||
self->stsap_sel, IAS_KERNEL_ATTR);
|
self->stsap_sel, IAS_KERNEL_ATTR);
|
||||||
irias_insert_object(self->ias_obj);
|
irias_insert_object(self->ias_obj);
|
||||||
@ -1825,7 +1831,7 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
|
|||||||
struct irda_ias_set *ias_opt;
|
struct irda_ias_set *ias_opt;
|
||||||
struct ias_object *ias_obj;
|
struct ias_object *ias_obj;
|
||||||
struct ias_attrib * ias_attr; /* Attribute in IAS object */
|
struct ias_attrib * ias_attr; /* Attribute in IAS object */
|
||||||
int opt;
|
int opt, free_ias = 0;
|
||||||
|
|
||||||
IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
|
IRDA_DEBUG(2, "%s(%p)\n", __FUNCTION__, self);
|
||||||
|
|
||||||
@ -1881,11 +1887,20 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
|
|||||||
/* Create a new object */
|
/* Create a new object */
|
||||||
ias_obj = irias_new_object(ias_opt->irda_class_name,
|
ias_obj = irias_new_object(ias_opt->irda_class_name,
|
||||||
jiffies);
|
jiffies);
|
||||||
|
if (ias_obj == NULL) {
|
||||||
|
kfree(ias_opt);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
free_ias = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do we have the attribute already ? */
|
/* Do we have the attribute already ? */
|
||||||
if(irias_find_attrib(ias_obj, ias_opt->irda_attrib_name)) {
|
if(irias_find_attrib(ias_obj, ias_opt->irda_attrib_name)) {
|
||||||
kfree(ias_opt);
|
kfree(ias_opt);
|
||||||
|
if (free_ias) {
|
||||||
|
kfree(ias_obj->name);
|
||||||
|
kfree(ias_obj);
|
||||||
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1904,6 +1919,11 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
|
|||||||
if(ias_opt->attribute.irda_attrib_octet_seq.len >
|
if(ias_opt->attribute.irda_attrib_octet_seq.len >
|
||||||
IAS_MAX_OCTET_STRING) {
|
IAS_MAX_OCTET_STRING) {
|
||||||
kfree(ias_opt);
|
kfree(ias_opt);
|
||||||
|
if (free_ias) {
|
||||||
|
kfree(ias_obj->name);
|
||||||
|
kfree(ias_obj);
|
||||||
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
/* Add an octet sequence attribute */
|
/* Add an octet sequence attribute */
|
||||||
@ -1932,6 +1952,10 @@ static int irda_setsockopt(struct socket *sock, int level, int optname,
|
|||||||
break;
|
break;
|
||||||
default :
|
default :
|
||||||
kfree(ias_opt);
|
kfree(ias_opt);
|
||||||
|
if (free_ias) {
|
||||||
|
kfree(ias_obj->name);
|
||||||
|
kfree(ias_obj);
|
||||||
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
irias_insert_object(ias_obj);
|
irias_insert_object(ias_obj);
|
||||||
|
@ -3593,27 +3593,29 @@ static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
|
|||||||
/* old ipsecrequest */
|
/* old ipsecrequest */
|
||||||
int mode = pfkey_mode_from_xfrm(mp->mode);
|
int mode = pfkey_mode_from_xfrm(mp->mode);
|
||||||
if (mode < 0)
|
if (mode < 0)
|
||||||
return -EINVAL;
|
goto err;
|
||||||
if (set_ipsecrequest(skb, mp->proto, mode,
|
if (set_ipsecrequest(skb, mp->proto, mode,
|
||||||
(mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE),
|
(mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE),
|
||||||
mp->reqid, mp->old_family,
|
mp->reqid, mp->old_family,
|
||||||
&mp->old_saddr, &mp->old_daddr) < 0) {
|
&mp->old_saddr, &mp->old_daddr) < 0)
|
||||||
return -EINVAL;
|
goto err;
|
||||||
}
|
|
||||||
|
|
||||||
/* new ipsecrequest */
|
/* new ipsecrequest */
|
||||||
if (set_ipsecrequest(skb, mp->proto, mode,
|
if (set_ipsecrequest(skb, mp->proto, mode,
|
||||||
(mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE),
|
(mp->reqid ? IPSEC_LEVEL_UNIQUE : IPSEC_LEVEL_REQUIRE),
|
||||||
mp->reqid, mp->new_family,
|
mp->reqid, mp->new_family,
|
||||||
&mp->new_saddr, &mp->new_daddr) < 0) {
|
&mp->new_saddr, &mp->new_daddr) < 0)
|
||||||
return -EINVAL;
|
goto err;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* broadcast migrate message to sockets */
|
/* broadcast migrate message to sockets */
|
||||||
pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
|
pfkey_broadcast(skb, GFP_ATOMIC, BROADCAST_ALL, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err:
|
||||||
|
kfree_skb(skb);
|
||||||
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
|
static int pfkey_send_migrate(struct xfrm_selector *sel, u8 dir, u8 type,
|
||||||
|
@ -392,11 +392,14 @@ int rfkill_register(struct rfkill *rfkill)
|
|||||||
rfkill_led_trigger_register(rfkill);
|
rfkill_led_trigger_register(rfkill);
|
||||||
|
|
||||||
error = rfkill_add_switch(rfkill);
|
error = rfkill_add_switch(rfkill);
|
||||||
if (error)
|
if (error) {
|
||||||
|
rfkill_led_trigger_unregister(rfkill);
|
||||||
return error;
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
error = device_add(dev);
|
error = device_add(dev);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
rfkill_led_trigger_unregister(rfkill);
|
||||||
rfkill_remove_switch(rfkill);
|
rfkill_remove_switch(rfkill);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user