aboutsummaryrefslogtreecommitdiffstats
path: root/net/xfrm
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-01 17:59:04 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-01 17:59:04 -0500
commit2774c131b1d19920b4587db1cfbd6f0750ad1f15 (patch)
tree3a0482c727cf4dcc046a211214f12459dcba8271 /net/xfrm
parent69ead7afdf6028184f713a77376ee26f8aaafdcd (diff)
xfrm: Handle blackhole route creation via afinfo.
That way we don't have to potentially do this in every xfrm_lookup() caller. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r--net/xfrm/xfrm_policy.c46
1 files changed, 26 insertions, 20 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c
index f4c7467a614e..0248afa11cda 100644
--- a/net/xfrm/xfrm_policy.c
+++ b/net/xfrm/xfrm_policy.c
@@ -1735,14 +1735,31 @@ error:
1735 return ERR_PTR(err); 1735 return ERR_PTR(err);
1736} 1736}
1737 1737
1738static struct dst_entry *make_blackhole(struct net *net, u16 family,
1739 struct dst_entry *dst_orig)
1740{
1741 struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
1742 struct dst_entry *ret;
1743
1744 if (!afinfo) {
1745 dst_release(dst_orig);
1746 ret = ERR_PTR(-EINVAL);
1747 } else {
1748 ret = afinfo->blackhole_route(net, dst_orig);
1749 }
1750 xfrm_policy_put_afinfo(afinfo);
1751
1752 return ret;
1753}
1754
1738/* Main function: finds/creates a bundle for given flow. 1755/* Main function: finds/creates a bundle for given flow.
1739 * 1756 *
1740 * At the moment we eat a raw IP route. Mostly to speed up lookups 1757 * At the moment we eat a raw IP route. Mostly to speed up lookups
1741 * on interfaces with disabled IPsec. 1758 * on interfaces with disabled IPsec.
1742 */ 1759 */
1743int __xfrm_lookup(struct net *net, struct dst_entry **dst_p, 1760int xfrm_lookup(struct net *net, struct dst_entry **dst_p,
1744 const struct flowi *fl, 1761 const struct flowi *fl,
1745 struct sock *sk, int flags) 1762 struct sock *sk, int flags)
1746{ 1763{
1747 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; 1764 struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX];
1748 struct flow_cache_object *flo; 1765 struct flow_cache_object *flo;
@@ -1829,7 +1846,12 @@ restart:
1829 dst_release(dst); 1846 dst_release(dst);
1830 xfrm_pols_put(pols, drop_pols); 1847 xfrm_pols_put(pols, drop_pols);
1831 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); 1848 XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES);
1832 return -EREMOTE; 1849
1850 dst = make_blackhole(net, family, dst_orig);
1851 if (IS_ERR(dst))
1852 return PTR_ERR(dst);
1853 *dst_p = dst;
1854 return 0;
1833 } 1855 }
1834 if (fl->flags & FLOWI_FLAG_CAN_SLEEP) { 1856 if (fl->flags & FLOWI_FLAG_CAN_SLEEP) {
1835 DECLARE_WAITQUEUE(wait, current); 1857 DECLARE_WAITQUEUE(wait, current);
@@ -1895,22 +1917,6 @@ dropdst:
1895 xfrm_pols_put(pols, drop_pols); 1917 xfrm_pols_put(pols, drop_pols);
1896 return err; 1918 return err;
1897} 1919}
1898EXPORT_SYMBOL(__xfrm_lookup);
1899
1900int xfrm_lookup(struct net *net, struct dst_entry **dst_p,
1901 const struct flowi *fl,
1902 struct sock *sk, int flags)
1903{
1904 int err = __xfrm_lookup(net, dst_p, fl, sk, flags);
1905
1906 if (err == -EREMOTE) {
1907 dst_release(*dst_p);
1908 *dst_p = NULL;
1909 err = -EAGAIN;
1910 }
1911
1912 return err;
1913}
1914EXPORT_SYMBOL(xfrm_lookup); 1920EXPORT_SYMBOL(xfrm_lookup);
1915 1921
1916static inline int 1922static inline int