diff options
author | David S. Miller <davem@davemloft.net> | 2011-03-02 16:27:41 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-03-02 16:27:41 -0500 |
commit | 452edd598f60522c11f7f88fdbab27eb36509d1a (patch) | |
tree | df1510e9848e591a412c8bfa724253470c48c4c2 /net/xfrm | |
parent | 3872b284087081ee5cb0e4630954c2f7a2153cf5 (diff) |
xfrm: Return dst directly from xfrm_lookup()
Instead of on the stack.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/xfrm')
-rw-r--r-- | net/xfrm/xfrm_policy.c | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 0248afa11cda..b1932a629ef8 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1757,14 +1757,14 @@ static struct dst_entry *make_blackhole(struct net *net, u16 family, | |||
1757 | * 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 |
1758 | * on interfaces with disabled IPsec. | 1758 | * on interfaces with disabled IPsec. |
1759 | */ | 1759 | */ |
1760 | int xfrm_lookup(struct net *net, struct dst_entry **dst_p, | 1760 | struct dst_entry *xfrm_lookup(struct net *net, struct dst_entry *dst_orig, |
1761 | const struct flowi *fl, | 1761 | const struct flowi *fl, |
1762 | struct sock *sk, int flags) | 1762 | struct sock *sk, int flags) |
1763 | { | 1763 | { |
1764 | struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; | 1764 | struct xfrm_policy *pols[XFRM_POLICY_TYPE_MAX]; |
1765 | struct flow_cache_object *flo; | 1765 | struct flow_cache_object *flo; |
1766 | struct xfrm_dst *xdst; | 1766 | struct xfrm_dst *xdst; |
1767 | struct dst_entry *dst, *dst_orig = *dst_p, *route; | 1767 | struct dst_entry *dst, *route; |
1768 | u16 family = dst_orig->ops->family; | 1768 | u16 family = dst_orig->ops->family; |
1769 | u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); | 1769 | u8 dir = policy_to_flow_dir(XFRM_POLICY_OUT); |
1770 | int i, err, num_pols, num_xfrms = 0, drop_pols = 0; | 1770 | int i, err, num_pols, num_xfrms = 0, drop_pols = 0; |
@@ -1847,11 +1847,7 @@ restart: | |||
1847 | xfrm_pols_put(pols, drop_pols); | 1847 | xfrm_pols_put(pols, drop_pols); |
1848 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); | 1848 | XFRM_INC_STATS(net, LINUX_MIB_XFRMOUTNOSTATES); |
1849 | 1849 | ||
1850 | dst = make_blackhole(net, family, dst_orig); | 1850 | return make_blackhole(net, family, dst_orig); |
1851 | if (IS_ERR(dst)) | ||
1852 | return PTR_ERR(dst); | ||
1853 | *dst_p = dst; | ||
1854 | return 0; | ||
1855 | } | 1851 | } |
1856 | if (fl->flags & FLOWI_FLAG_CAN_SLEEP) { | 1852 | if (fl->flags & FLOWI_FLAG_CAN_SLEEP) { |
1857 | DECLARE_WAITQUEUE(wait, current); | 1853 | DECLARE_WAITQUEUE(wait, current); |
@@ -1895,27 +1891,28 @@ no_transform: | |||
1895 | goto error; | 1891 | goto error; |
1896 | } else if (num_xfrms > 0) { | 1892 | } else if (num_xfrms > 0) { |
1897 | /* Flow transformed */ | 1893 | /* Flow transformed */ |
1898 | *dst_p = dst; | ||
1899 | dst_release(dst_orig); | 1894 | dst_release(dst_orig); |
1900 | } else { | 1895 | } else { |
1901 | /* Flow passes untransformed */ | 1896 | /* Flow passes untransformed */ |
1902 | dst_release(dst); | 1897 | dst_release(dst); |
1898 | dst = dst_orig; | ||
1903 | } | 1899 | } |
1904 | ok: | 1900 | ok: |
1905 | xfrm_pols_put(pols, drop_pols); | 1901 | xfrm_pols_put(pols, drop_pols); |
1906 | return 0; | 1902 | return dst; |
1907 | 1903 | ||
1908 | nopol: | 1904 | nopol: |
1909 | if (!(flags & XFRM_LOOKUP_ICMP)) | 1905 | if (!(flags & XFRM_LOOKUP_ICMP)) { |
1906 | dst = dst_orig; | ||
1910 | goto ok; | 1907 | goto ok; |
1908 | } | ||
1911 | err = -ENOENT; | 1909 | err = -ENOENT; |
1912 | error: | 1910 | error: |
1913 | dst_release(dst); | 1911 | dst_release(dst); |
1914 | dropdst: | 1912 | dropdst: |
1915 | dst_release(dst_orig); | 1913 | dst_release(dst_orig); |
1916 | *dst_p = NULL; | ||
1917 | xfrm_pols_put(pols, drop_pols); | 1914 | xfrm_pols_put(pols, drop_pols); |
1918 | return err; | 1915 | return ERR_PTR(err); |
1919 | } | 1916 | } |
1920 | EXPORT_SYMBOL(xfrm_lookup); | 1917 | EXPORT_SYMBOL(xfrm_lookup); |
1921 | 1918 | ||
@@ -2175,7 +2172,7 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) | |||
2175 | struct net *net = dev_net(skb->dev); | 2172 | struct net *net = dev_net(skb->dev); |
2176 | struct flowi fl; | 2173 | struct flowi fl; |
2177 | struct dst_entry *dst; | 2174 | struct dst_entry *dst; |
2178 | int res; | 2175 | int res = 0; |
2179 | 2176 | ||
2180 | if (xfrm_decode_session(skb, &fl, family) < 0) { | 2177 | if (xfrm_decode_session(skb, &fl, family) < 0) { |
2181 | XFRM_INC_STATS(net, LINUX_MIB_XFRMFWDHDRERROR); | 2178 | XFRM_INC_STATS(net, LINUX_MIB_XFRMFWDHDRERROR); |
@@ -2183,9 +2180,12 @@ int __xfrm_route_forward(struct sk_buff *skb, unsigned short family) | |||
2183 | } | 2180 | } |
2184 | 2181 | ||
2185 | skb_dst_force(skb); | 2182 | skb_dst_force(skb); |
2186 | dst = skb_dst(skb); | ||
2187 | 2183 | ||
2188 | res = xfrm_lookup(net, &dst, &fl, NULL, 0) == 0; | 2184 | dst = xfrm_lookup(net, skb_dst(skb), &fl, NULL, 0); |
2185 | if (IS_ERR(dst)) { | ||
2186 | res = 1; | ||
2187 | dst = NULL; | ||
2188 | } | ||
2189 | skb_dst_set(skb, dst); | 2189 | skb_dst_set(skb, dst); |
2190 | return res; | 2190 | return res; |
2191 | } | 2191 | } |