aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_state.c58
1 files changed, 30 insertions, 28 deletions
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 64780a6f7b86..1522f19f273a 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -1644,27 +1644,26 @@ static void xfrm_replay_timer_handler(unsigned long data)
1644} 1644}
1645 1645
1646static LIST_HEAD(xfrm_km_list); 1646static LIST_HEAD(xfrm_km_list);
1647static DEFINE_RWLOCK(xfrm_km_lock);
1648 1647
1649void km_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c) 1648void km_policy_notify(struct xfrm_policy *xp, int dir, const struct km_event *c)
1650{ 1649{
1651 struct xfrm_mgr *km; 1650 struct xfrm_mgr *km;
1652 1651
1653 read_lock(&xfrm_km_lock); 1652 rcu_read_lock();
1654 list_for_each_entry(km, &xfrm_km_list, list) 1653 list_for_each_entry_rcu(km, &xfrm_km_list, list)
1655 if (km->notify_policy) 1654 if (km->notify_policy)
1656 km->notify_policy(xp, dir, c); 1655 km->notify_policy(xp, dir, c);
1657 read_unlock(&xfrm_km_lock); 1656 rcu_read_unlock();
1658} 1657}
1659 1658
1660void km_state_notify(struct xfrm_state *x, const struct km_event *c) 1659void km_state_notify(struct xfrm_state *x, const struct km_event *c)
1661{ 1660{
1662 struct xfrm_mgr *km; 1661 struct xfrm_mgr *km;
1663 read_lock(&xfrm_km_lock); 1662 rcu_read_lock();
1664 list_for_each_entry(km, &xfrm_km_list, list) 1663 list_for_each_entry_rcu(km, &xfrm_km_list, list)
1665 if (km->notify) 1664 if (km->notify)
1666 km->notify(x, c); 1665 km->notify(x, c);
1667 read_unlock(&xfrm_km_lock); 1666 rcu_read_unlock();
1668} 1667}
1669 1668
1670EXPORT_SYMBOL(km_policy_notify); 1669EXPORT_SYMBOL(km_policy_notify);
@@ -1694,13 +1693,13 @@ int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol)
1694 int err = -EINVAL, acqret; 1693 int err = -EINVAL, acqret;
1695 struct xfrm_mgr *km; 1694 struct xfrm_mgr *km;
1696 1695
1697 read_lock(&xfrm_km_lock); 1696 rcu_read_lock();
1698 list_for_each_entry(km, &xfrm_km_list, list) { 1697 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1699 acqret = km->acquire(x, t, pol); 1698 acqret = km->acquire(x, t, pol);
1700 if (!acqret) 1699 if (!acqret)
1701 err = acqret; 1700 err = acqret;
1702 } 1701 }
1703 read_unlock(&xfrm_km_lock); 1702 rcu_read_unlock();
1704 return err; 1703 return err;
1705} 1704}
1706EXPORT_SYMBOL(km_query); 1705EXPORT_SYMBOL(km_query);
@@ -1710,14 +1709,14 @@ int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport)
1710 int err = -EINVAL; 1709 int err = -EINVAL;
1711 struct xfrm_mgr *km; 1710 struct xfrm_mgr *km;
1712 1711
1713 read_lock(&xfrm_km_lock); 1712 rcu_read_lock();
1714 list_for_each_entry(km, &xfrm_km_list, list) { 1713 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1715 if (km->new_mapping) 1714 if (km->new_mapping)
1716 err = km->new_mapping(x, ipaddr, sport); 1715 err = km->new_mapping(x, ipaddr, sport);
1717 if (!err) 1716 if (!err)
1718 break; 1717 break;
1719 } 1718 }
1720 read_unlock(&xfrm_km_lock); 1719 rcu_read_unlock();
1721 return err; 1720 return err;
1722} 1721}
1723EXPORT_SYMBOL(km_new_mapping); 1722EXPORT_SYMBOL(km_new_mapping);
@@ -1746,15 +1745,15 @@ int km_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
1746 int ret; 1745 int ret;
1747 struct xfrm_mgr *km; 1746 struct xfrm_mgr *km;
1748 1747
1749 read_lock(&xfrm_km_lock); 1748 rcu_read_lock();
1750 list_for_each_entry(km, &xfrm_km_list, list) { 1749 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1751 if (km->migrate) { 1750 if (km->migrate) {
1752 ret = km->migrate(sel, dir, type, m, num_migrate, k); 1751 ret = km->migrate(sel, dir, type, m, num_migrate, k);
1753 if (!ret) 1752 if (!ret)
1754 err = ret; 1753 err = ret;
1755 } 1754 }
1756 } 1755 }
1757 read_unlock(&xfrm_km_lock); 1756 rcu_read_unlock();
1758 return err; 1757 return err;
1759} 1758}
1760EXPORT_SYMBOL(km_migrate); 1759EXPORT_SYMBOL(km_migrate);
@@ -1766,15 +1765,15 @@ int km_report(struct net *net, u8 proto, struct xfrm_selector *sel, xfrm_address
1766 int ret; 1765 int ret;
1767 struct xfrm_mgr *km; 1766 struct xfrm_mgr *km;
1768 1767
1769 read_lock(&xfrm_km_lock); 1768 rcu_read_lock();
1770 list_for_each_entry(km, &xfrm_km_list, list) { 1769 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1771 if (km->report) { 1770 if (km->report) {
1772 ret = km->report(net, proto, sel, addr); 1771 ret = km->report(net, proto, sel, addr);
1773 if (!ret) 1772 if (!ret)
1774 err = ret; 1773 err = ret;
1775 } 1774 }
1776 } 1775 }
1777 read_unlock(&xfrm_km_lock); 1776 rcu_read_unlock();
1778 return err; 1777 return err;
1779} 1778}
1780EXPORT_SYMBOL(km_report); 1779EXPORT_SYMBOL(km_report);
@@ -1798,14 +1797,14 @@ int xfrm_user_policy(struct sock *sk, int optname, u8 __user *optval, int optlen
1798 goto out; 1797 goto out;
1799 1798
1800 err = -EINVAL; 1799 err = -EINVAL;
1801 read_lock(&xfrm_km_lock); 1800 rcu_read_lock();
1802 list_for_each_entry(km, &xfrm_km_list, list) { 1801 list_for_each_entry_rcu(km, &xfrm_km_list, list) {
1803 pol = km->compile_policy(sk, optname, data, 1802 pol = km->compile_policy(sk, optname, data,
1804 optlen, &err); 1803 optlen, &err);
1805 if (err >= 0) 1804 if (err >= 0)
1806 break; 1805 break;
1807 } 1806 }
1808 read_unlock(&xfrm_km_lock); 1807 rcu_read_unlock();
1809 1808
1810 if (err >= 0) { 1809 if (err >= 0) {
1811 xfrm_sk_policy_insert(sk, err, pol); 1810 xfrm_sk_policy_insert(sk, err, pol);
@@ -1819,20 +1818,23 @@ out:
1819} 1818}
1820EXPORT_SYMBOL(xfrm_user_policy); 1819EXPORT_SYMBOL(xfrm_user_policy);
1821 1820
1821static DEFINE_SPINLOCK(xfrm_km_lock);
1822
1822int xfrm_register_km(struct xfrm_mgr *km) 1823int xfrm_register_km(struct xfrm_mgr *km)
1823{ 1824{
1824 write_lock_bh(&xfrm_km_lock); 1825 spin_lock_bh(&xfrm_km_lock);
1825 list_add_tail(&km->list, &xfrm_km_list); 1826 list_add_tail_rcu(&km->list, &xfrm_km_list);
1826 write_unlock_bh(&xfrm_km_lock); 1827 spin_unlock_bh(&xfrm_km_lock);
1827 return 0; 1828 return 0;
1828} 1829}
1829EXPORT_SYMBOL(xfrm_register_km); 1830EXPORT_SYMBOL(xfrm_register_km);
1830 1831
1831int xfrm_unregister_km(struct xfrm_mgr *km) 1832int xfrm_unregister_km(struct xfrm_mgr *km)
1832{ 1833{
1833 write_lock_bh(&xfrm_km_lock); 1834 spin_lock_bh(&xfrm_km_lock);
1834 list_del(&km->list); 1835 list_del_rcu(&km->list);
1835 write_unlock_bh(&xfrm_km_lock); 1836 spin_unlock_bh(&xfrm_km_lock);
1837 synchronize_rcu();
1836 return 0; 1838 return 0;
1837} 1839}
1838EXPORT_SYMBOL(xfrm_unregister_km); 1840EXPORT_SYMBOL(xfrm_unregister_km);