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:
  ipsec: Fix deadlock in xfrm_state management.
  ipv: Re-enable IP when MTU > 68
  net/xfrm: Use an IS_ERR test rather than a NULL test
  ath9: Fix ath_rx_flush_tid() for IRQs disabled kernel warning message.
  ath9k: Incorrect key used when group and pairwise ciphers are different.
  rt2x00: Compiler warning unmasked by fix of BUILD_BUG_ON
  mac80211: Fix debugfs union misuse and pointer corruption
  wireless/libertas/if_cs.c: fix memory leaks
  orinoco: Multicast to the specified addresses
  iwlwifi: fix 64bit platform firmware loading
  iwlwifi: fix apm_stop (wrong bit polarity for FLAG_INIT_DONE)
  iwlwifi: workaround interrupt handling no some platforms
  iwlwifi: do not use GFP_DMA in iwl_tx_queue_init
  net/wireless/Kconfig: clarify the description for CONFIG_WIRELESS_EXT_SYSFS
  net: Unbreak userspace usage of linux/mroute.h
  pkt_sched: Fix locking of qdisc_root with qdisc_root_sleeping_lock()
  ipv6: When we droped a packet, we should return NET_RX_DROP instead of 0
This commit is contained in:
Linus Torvalds 2008-09-02 21:02:14 -07:00
commit d26acd92fa
29 changed files with 102 additions and 90 deletions

View File

@ -7285,15 +7285,15 @@ ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
}
break;
case ATH9K_CIPHER_WEP:
if (k->kv_len < 40 / NBBY) {
if (k->kv_len < LEN_WEP40) {
DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
"%s: WEP key length %u too small\n",
__func__, k->kv_len);
return false;
}
if (k->kv_len <= 40 / NBBY)
if (k->kv_len <= LEN_WEP40)
keyType = AR_KEYTABLE_TYPE_40;
else if (k->kv_len <= 104 / NBBY)
else if (k->kv_len <= LEN_WEP104)
keyType = AR_KEYTABLE_TYPE_104;
else
keyType = AR_KEYTABLE_TYPE_128;
@ -7313,7 +7313,7 @@ ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
if (k->kv_len <= 104 / NBBY)
if (k->kv_len <= LEN_WEP104)
key4 &= 0xff;
if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {

View File

@ -206,7 +206,8 @@ static int ath_key_config(struct ath_softc *sc,
if (!ret)
return -EIO;
sc->sc_keytype = hk.kv_type;
if (mac)
sc->sc_keytype = hk.kv_type;
return 0;
}
@ -756,7 +757,8 @@ static int ath9k_set_key(struct ieee80211_hw *hw,
key->hw_key_idx = key->keyidx;
/* push IV and Michael MIC generation to stack */
key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
if (key->alg == ALG_TKIP)
key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
}
break;
case DISABLE_KEY:

View File

@ -360,8 +360,9 @@ static void ath_rx_flush_tid(struct ath_softc *sc,
struct ath_arx_tid *rxtid, int drop)
{
struct ath_rxbuf *rxbuf;
unsigned long flag;
spin_lock_bh(&rxtid->tidlock);
spin_lock_irqsave(&rxtid->tidlock, flag);
while (rxtid->baw_head != rxtid->baw_tail) {
rxbuf = rxtid->rxbuf + rxtid->baw_head;
if (!rxbuf->rx_wbuf) {
@ -382,7 +383,7 @@ static void ath_rx_flush_tid(struct ath_softc *sc,
INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
}
spin_unlock_bh(&rxtid->tidlock);
spin_unlock_irqrestore(&rxtid->tidlock, flag);
}
static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc,

View File

@ -474,8 +474,8 @@ static void iwl4965_apm_stop(struct iwl_priv *priv)
iwl_set_bit(priv, CSR_RESET, CSR_RESET_REG_FLAG_SW_RESET);
udelay(10);
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
/* clear "init complete" move adapter D0A* --> D0U state */
iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
spin_unlock_irqrestore(&priv->lock, flags);
}

View File

@ -145,7 +145,8 @@ static void iwl5000_apm_stop(struct iwl_priv *priv)
udelay(10);
iwl_set_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
/* clear "init complete" move adapter D0A* --> D0U state */
iwl_clear_bit(priv, CSR_GP_CNTRL, CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
spin_unlock_irqrestore(&priv->lock, flags);
}
@ -577,14 +578,11 @@ static int iwl5000_load_section(struct iwl_priv *priv,
FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
/* FIME: write the MSB of the phy_addr in CTRL1
* iwl_write_direct32(priv,
IWL_FH_TFDIB_CTRL1_REG(IWL_FH_SRVC_CHNL),
((phy_addr & MSB_MSK)
<< FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_count);
*/
iwl_write_direct32(priv,
FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL), byte_cnt);
FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
(iwl_get_dma_hi_address(phy_addr)
<< FH_MEM_TFDIB_REG1_ADDR_BITSHIFT) | byte_cnt);
iwl_write_direct32(priv,
FH_TCSR_CHNL_TX_BUF_STS_REG(FH_SRVC_CHNL),
1 << FH_TCSR_CHNL_TX_BUF_STS_REG_POS_TB_NUM |

View File

@ -2602,6 +2602,7 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
{
struct iwl_priv *priv = hw->priv;
int ret;
u16 pci_cmd;
IWL_DEBUG_MAC80211("enter\n");
@ -2612,6 +2613,13 @@ static int iwl4965_mac_start(struct ieee80211_hw *hw)
pci_restore_state(priv->pci_dev);
pci_enable_msi(priv->pci_dev);
/* enable interrupts if needed: hw bug w/a */
pci_read_config_word(priv->pci_dev, PCI_COMMAND, &pci_cmd);
if (pci_cmd & PCI_COMMAND_INTX_DISABLE) {
pci_cmd &= ~PCI_COMMAND_INTX_DISABLE;
pci_write_config_word(priv->pci_dev, PCI_COMMAND, pci_cmd);
}
ret = request_irq(priv->pci_dev->irq, iwl4965_isr, IRQF_SHARED,
DRV_NAME, priv);
if (ret) {

View File

@ -287,6 +287,7 @@
#define FH_RSSR_CHNL0_RX_STATUS_CHNL_IDLE (0x01000000)
#define FH_MEM_TFDIB_REG1_ADDR_BITSHIFT 28
/**
* Transmit DMA Channel Control/Status Registers (TCSR)

View File

@ -426,7 +426,7 @@ static int iwl_tx_queue_init(struct iwl_priv *priv,
continue;
}
txq->cmd[i] = kmalloc(len, GFP_KERNEL | GFP_DMA);
txq->cmd[i] = kmalloc(len, GFP_KERNEL);
if (!txq->cmd[i])
return -ENOMEM;
}

View File

@ -595,7 +595,7 @@ static int if_cs_prog_helper(struct if_cs_card *card)
if (ret < 0) {
lbs_pr_err("can't download helper at 0x%x, ret %d\n",
sent, ret);
goto done;
goto err_release;
}
if (count == 0)
@ -604,9 +604,8 @@ static int if_cs_prog_helper(struct if_cs_card *card)
sent += count;
}
err_release:
release_firmware(fw);
ret = 0;
done:
lbs_deb_leave_args(LBS_DEB_CS, "ret %d", ret);
return ret;
@ -676,14 +675,8 @@ static int if_cs_prog_real(struct if_cs_card *card)
}
ret = if_cs_poll_while_fw_download(card, IF_CS_SCRATCH, 0x5a);
if (ret < 0) {
if (ret < 0)
lbs_pr_err("firmware download failed\n");
goto err_release;
}
ret = 0;
goto done;
err_release:
release_firmware(fw);

View File

@ -1970,6 +1970,9 @@ __orinoco_set_multicast_list(struct net_device *dev)
priv->promiscuous = promisc;
}
/* If we're not in promiscuous mode, then we need to set the
* group address if either we want to multicast, or if we were
* multicasting and want to stop */
if (! promisc && (mc_count || priv->mc_count) ) {
struct dev_mc_list *p = dev->mc_list;
struct hermes_multicast mclist;
@ -1989,9 +1992,10 @@ __orinoco_set_multicast_list(struct net_device *dev)
printk(KERN_WARNING "%s: Multicast list is "
"longer than mc_count\n", dev->name);
err = hermes_write_ltv(hw, USER_BAP, HERMES_RID_CNFGROUPADDRESSES,
HERMES_BYTES_TO_RECLEN(priv->mc_count * ETH_ALEN),
&mclist);
err = hermes_write_ltv(hw, USER_BAP,
HERMES_RID_CNFGROUPADDRESSES,
HERMES_BYTES_TO_RECLEN(mc_count * ETH_ALEN),
&mclist);
if (err)
printk(KERN_ERR "%s: Error %d setting multicast list.\n",
dev->name, err);

View File

@ -136,7 +136,7 @@ struct rt2x00_field32 {
*/
#define is_power_of_two(x) ( !((x) & ((x)-1)) )
#define low_bit_mask(x) ( ((x)-1) & ~(x) )
#define is_valid_mask(x) is_power_of_two(1 + (x) + low_bit_mask(x))
#define is_valid_mask(x) is_power_of_two(1LU + (x) + low_bit_mask(x))
/*
* Macro's to find first set bit in a variable.
@ -173,8 +173,7 @@ struct rt2x00_field32 {
* does not exceed the given typelimit.
*/
#define FIELD_CHECK(__mask, __type) \
BUILD_BUG_ON(!__builtin_constant_p(__mask) || \
!(__mask) || \
BUILD_BUG_ON(!(__mask) || \
!is_valid_mask(__mask) || \
(__mask) != (__type)(__mask)) \

View File

@ -297,7 +297,6 @@ unifdef-y += parport.h
unifdef-y += patchkey.h
unifdef-y += pci.h
unifdef-y += personality.h
unifdef-y += pim.h
unifdef-y += pktcdvd.h
unifdef-y += pmu.h
unifdef-y += poll.h

View File

@ -6,7 +6,6 @@
#ifdef __KERNEL__
#include <linux/in.h>
#endif
#include <linux/pim.h>
/*
* Based on the MROUTING 3.5 defines primarily to keep
@ -130,6 +129,7 @@ struct igmpmsg
*/
#ifdef __KERNEL__
#include <linux/pim.h>
#include <net/sock.h>
#ifdef CONFIG_IP_MROUTE

View File

@ -115,6 +115,7 @@ struct sioc_mif_req6
#ifdef __KERNEL__
#include <linux/pim.h>
#include <linux/skbuff.h> /* for struct sk_buff_head */
#ifdef CONFIG_IPV6_MROUTE

View File

@ -3,22 +3,6 @@
#include <asm/byteorder.h>
#ifndef __KERNEL__
struct pim {
#if defined(__LITTLE_ENDIAN_BITFIELD)
__u8 pim_type:4, /* PIM message type */
pim_ver:4; /* PIM version */
#elif defined(__BIG_ENDIAN_BITFIELD)
__u8 pim_ver:4; /* PIM version */
pim_type:4; /* PIM message type */
#endif
__u8 pim_rsv; /* Reserved */
__be16 pim_cksum; /* Checksum */
};
#define PIM_MINLEN 8
#endif
/* Message types - V1 */
#define PIM_V1_VERSION __constant_htonl(0x10000000)
#define PIM_V1_REGISTER 1
@ -27,7 +11,6 @@ struct pim {
#define PIM_VERSION 2
#define PIM_REGISTER 1
#if defined(__KERNEL__)
#define PIM_NULL_REGISTER __constant_htonl(0x40000000)
/* PIMv2 register message header layout (ietf-draft-idmr-pimvsm-v2-00.ps */
@ -42,4 +25,3 @@ struct pimreghdr
struct sk_buff;
extern int pim_rcv_v1(struct sk_buff *);
#endif
#endif

View File

@ -1029,6 +1029,11 @@ static void inetdev_changename(struct net_device *dev, struct in_device *in_dev)
}
}
static inline bool inetdev_valid_mtu(unsigned mtu)
{
return mtu >= 68;
}
/* Called only under RTNL semaphore */
static int inetdev_event(struct notifier_block *this, unsigned long event,
@ -1048,6 +1053,10 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
IN_DEV_CONF_SET(in_dev, NOXFRM, 1);
IN_DEV_CONF_SET(in_dev, NOPOLICY, 1);
}
} else if (event == NETDEV_CHANGEMTU) {
/* Re-enabling IP */
if (inetdev_valid_mtu(dev->mtu))
in_dev = inetdev_init(dev);
}
goto out;
}
@ -1058,7 +1067,7 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
dev->ip_ptr = NULL;
break;
case NETDEV_UP:
if (dev->mtu < 68)
if (!inetdev_valid_mtu(dev->mtu))
break;
if (dev->flags & IFF_LOOPBACK) {
struct in_ifaddr *ifa;
@ -1080,9 +1089,9 @@ static int inetdev_event(struct notifier_block *this, unsigned long event,
ip_mc_down(in_dev);
break;
case NETDEV_CHANGEMTU:
if (dev->mtu >= 68)
if (inetdev_valid_mtu(dev->mtu))
break;
/* MTU falled under 68, disable IP */
/* disable IP when MTU is not enough */
case NETDEV_UNREGISTER:
inetdev_destroy(in_dev);
break;

View File

@ -377,14 +377,14 @@ static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
skb_checksum_complete(skb)) {
atomic_inc(&sk->sk_drops);
kfree_skb(skb);
return 0;
return NET_RX_DROP;
}
/* Charge it to the socket. */
if (sock_queue_rcv_skb(sk,skb)<0) {
atomic_inc(&sk->sk_drops);
kfree_skb(skb);
return 0;
return NET_RX_DROP;
}
return 0;
@ -429,7 +429,7 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
if (skb_checksum_complete(skb)) {
atomic_inc(&sk->sk_drops);
kfree_skb(skb);
return 0;
return NET_RX_DROP;
}
}

View File

@ -265,7 +265,7 @@ void ieee80211_debugfs_key_add_default(struct ieee80211_sub_if_data *sdata)
key = sdata->default_key;
if (key) {
sprintf(buf, "../keys/%d", key->debugfs.cnt);
sdata->debugfs.default_key =
sdata->common_debugfs.default_key =
debugfs_create_symlink("default_key",
sdata->debugfsdir, buf);
} else
@ -277,8 +277,8 @@ void ieee80211_debugfs_key_remove_default(struct ieee80211_sub_if_data *sdata)
if (!sdata)
return;
debugfs_remove(sdata->debugfs.default_key);
sdata->debugfs.default_key = NULL;
debugfs_remove(sdata->common_debugfs.default_key);
sdata->common_debugfs.default_key = NULL;
}
void ieee80211_debugfs_key_sta_del(struct ieee80211_key *key,

View File

@ -496,8 +496,10 @@ struct ieee80211_sub_if_data {
struct {
struct dentry *mode;
} monitor;
struct dentry *default_key;
} debugfs;
struct {
struct dentry *default_key;
} common_debugfs;
#ifdef CONFIG_MAC80211_MESH
struct dentry *mesh_stats_dir;

View File

@ -205,7 +205,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n, void *arg)
}
}
root_lock = qdisc_root_lock(q);
root_lock = qdisc_root_sleeping_lock(q);
if (tp == NULL) {
/* Proto-tcf does not exist, create new one */

View File

@ -75,7 +75,7 @@ static __inline__ int route4_fastmap_hash(u32 id, int iif)
static inline
void route4_reset_fastmap(struct Qdisc *q, struct route4_head *head, u32 id)
{
spinlock_t *root_lock = qdisc_root_lock(q);
spinlock_t *root_lock = qdisc_root_sleeping_lock(q);
spin_lock_bh(root_lock);
memset(head->fastmap, 0, sizeof(head->fastmap));

View File

@ -1169,8 +1169,8 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
if (q->stab && qdisc_dump_stab(skb, q->stab) < 0)
goto nla_put_failure;
if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
TCA_XSTATS, qdisc_root_lock(q), &d) < 0)
if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS,
qdisc_root_sleeping_lock(q), &d) < 0)
goto nla_put_failure;
if (q->ops->dump_stats && q->ops->dump_stats(q, &d) < 0)
@ -1461,8 +1461,8 @@ static int tc_fill_tclass(struct sk_buff *skb, struct Qdisc *q,
if (cl_ops->dump && cl_ops->dump(q, cl, skb, tcm) < 0)
goto nla_put_failure;
if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS,
TCA_XSTATS, qdisc_root_lock(q), &d) < 0)
if (gnet_stats_start_copy_compat(skb, TCA_STATS2, TCA_STATS, TCA_XSTATS,
qdisc_root_sleeping_lock(q), &d) < 0)
goto nla_put_failure;
if (cl_ops->dump_stats && cl_ops->dump_stats(q, cl, &d) < 0)

View File

@ -1754,7 +1754,7 @@ static void cbq_put(struct Qdisc *sch, unsigned long arg)
if (--cl->refcnt == 0) {
#ifdef CONFIG_NET_CLS_ACT
spinlock_t *root_lock = qdisc_root_lock(sch);
spinlock_t *root_lock = qdisc_root_sleeping_lock(sch);
struct cbq_sched_data *q = qdisc_priv(sch);
spin_lock_bh(root_lock);

View File

@ -1043,7 +1043,7 @@ static int htb_init(struct Qdisc *sch, struct nlattr *opt)
static int htb_dump(struct Qdisc *sch, struct sk_buff *skb)
{
spinlock_t *root_lock = qdisc_root_lock(sch);
spinlock_t *root_lock = qdisc_root_sleeping_lock(sch);
struct htb_sched *q = qdisc_priv(sch);
struct nlattr *nest;
struct tc_htb_glob gopt;
@ -1075,7 +1075,7 @@ static int htb_dump_class(struct Qdisc *sch, unsigned long arg,
struct sk_buff *skb, struct tcmsg *tcm)
{
struct htb_class *cl = (struct htb_class *)arg;
spinlock_t *root_lock = qdisc_root_lock(sch);
spinlock_t *root_lock = qdisc_root_sleeping_lock(sch);
struct nlattr *nest;
struct tc_htb_opt opt;

View File

@ -341,7 +341,7 @@ static int get_dist_table(struct Qdisc *sch, const struct nlattr *attr)
for (i = 0; i < n; i++)
d->table[i] = data[i];
root_lock = qdisc_root_lock(sch);
root_lock = qdisc_root_sleeping_lock(sch);
spin_lock_bh(root_lock);
d = xchg(&q->delay_dist, d);

View File

@ -161,7 +161,7 @@ teql_destroy(struct Qdisc* sch)
txq = netdev_get_tx_queue(master->dev, 0);
master->slaves = NULL;
root_lock = qdisc_root_lock(txq->qdisc);
root_lock = qdisc_root_sleeping_lock(txq->qdisc);
spin_lock_bh(root_lock);
qdisc_reset(txq->qdisc);
spin_unlock_bh(root_lock);

View File

@ -39,4 +39,5 @@ config WIRELESS_EXT_SYSFS
files in /sys/class/net/*/wireless/. The same information
is available via the ioctls as well.
Say Y if you have programs using it (we don't know of any).
Say Y if you have programs using it, like old versions of
hal.

View File

@ -1731,8 +1731,7 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
* We can't enlist stable bundles either.
*/
write_unlock_bh(&policy->lock);
if (dst)
dst_free(dst);
dst_free(dst);
if (pol_dead)
XFRM_INC_STATS(LINUX_MIB_XFRMOUTPOLDEAD);
@ -1748,8 +1747,7 @@ int __xfrm_lookup(struct dst_entry **dst_p, struct flowi *fl,
err = xfrm_dst_update_origin(dst, fl);
if (unlikely(err)) {
write_unlock_bh(&policy->lock);
if (dst)
dst_free(dst);
dst_free(dst);
XFRM_INC_STATS(LINUX_MIB_XFRMOUTBUNDLECHECKERROR);
goto error;
}

View File

@ -780,11 +780,13 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
{
unsigned int h;
struct hlist_node *entry;
struct xfrm_state *x, *x0;
struct xfrm_state *x, *x0, *to_put;
int acquire_in_progress = 0;
int error = 0;
struct xfrm_state *best = NULL;
to_put = NULL;
spin_lock_bh(&xfrm_state_lock);
h = xfrm_dst_hash(daddr, saddr, tmpl->reqid, family);
hlist_for_each_entry(x, entry, xfrm_state_bydst+h, bydst) {
@ -833,7 +835,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
if (tmpl->id.spi &&
(x0 = __xfrm_state_lookup(daddr, tmpl->id.spi,
tmpl->id.proto, family)) != NULL) {
xfrm_state_put(x0);
to_put = x0;
error = -EEXIST;
goto out;
}
@ -849,7 +851,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
error = security_xfrm_state_alloc_acquire(x, pol->security, fl->secid);
if (error) {
x->km.state = XFRM_STATE_DEAD;
xfrm_state_put(x);
to_put = x;
x = NULL;
goto out;
}
@ -870,7 +872,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
xfrm_hash_grow_check(x->bydst.next != NULL);
} else {
x->km.state = XFRM_STATE_DEAD;
xfrm_state_put(x);
to_put = x;
x = NULL;
error = -ESRCH;
}
@ -881,6 +883,8 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
else
*err = acquire_in_progress ? -EAGAIN : error;
spin_unlock_bh(&xfrm_state_lock);
if (to_put)
xfrm_state_put(to_put);
return x;
}
@ -1067,18 +1071,20 @@ static struct xfrm_state *__xfrm_find_acq_byseq(u32 seq);
int xfrm_state_add(struct xfrm_state *x)
{
struct xfrm_state *x1;
struct xfrm_state *x1, *to_put;
int family;
int err;
int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
family = x->props.family;
to_put = NULL;
spin_lock_bh(&xfrm_state_lock);
x1 = __xfrm_state_locate(x, use_spi, family);
if (x1) {
xfrm_state_put(x1);
to_put = x1;
x1 = NULL;
err = -EEXIST;
goto out;
@ -1088,7 +1094,7 @@ int xfrm_state_add(struct xfrm_state *x)
x1 = __xfrm_find_acq_byseq(x->km.seq);
if (x1 && ((x1->id.proto != x->id.proto) ||
xfrm_addr_cmp(&x1->id.daddr, &x->id.daddr, family))) {
xfrm_state_put(x1);
to_put = x1;
x1 = NULL;
}
}
@ -1110,6 +1116,9 @@ int xfrm_state_add(struct xfrm_state *x)
xfrm_state_put(x1);
}
if (to_put)
xfrm_state_put(to_put);
return err;
}
EXPORT_SYMBOL(xfrm_state_add);
@ -1269,10 +1278,12 @@ EXPORT_SYMBOL(xfrm_state_migrate);
int xfrm_state_update(struct xfrm_state *x)
{
struct xfrm_state *x1;
struct xfrm_state *x1, *to_put;
int err;
int use_spi = xfrm_id_proto_match(x->id.proto, IPSEC_PROTO_ANY);
to_put = NULL;
spin_lock_bh(&xfrm_state_lock);
x1 = __xfrm_state_locate(x, use_spi, x->props.family);
@ -1281,7 +1292,7 @@ int xfrm_state_update(struct xfrm_state *x)
goto out;
if (xfrm_state_kern(x1)) {
xfrm_state_put(x1);
to_put = x1;
err = -EEXIST;
goto out;
}
@ -1295,6 +1306,9 @@ int xfrm_state_update(struct xfrm_state *x)
out:
spin_unlock_bh(&xfrm_state_lock);
if (to_put)
xfrm_state_put(to_put);
if (err)
return err;