diff options
author | Florian Westphal <fw@strlen.de> | 2019-03-29 16:16:30 -0400 |
---|---|---|
committer | Steffen Klassert <steffen.klassert@secunet.com> | 2019-04-08 03:15:09 -0400 |
commit | 733a5fac2f15b55b9059230d098ed04341d2d884 (patch) | |
tree | 7d432c5ea1d82f7af81fcd0796e22f4b7b138d0b /net/ipv6 | |
parent | 1de70830066b72b6a8e259e5363f6c0bc4ba7bbc (diff) |
xfrm: remove afinfo pointer from xfrm_mode
Adds an EXPORT_SYMBOL for afinfo_get_rcu, as it will now be called from
ipv6 in case of CONFIG_IPV6=m.
This change has virtually no effect on vmlinux size, but it reduces
afinfo size and allows followup patch to make xfrm modes const.
v2: mark if (afinfo) tests as likely (Sabrina)
re-fetch afinfo according to inner_mode in xfrm_prepare_input().
Signed-off-by: Florian Westphal <fw@strlen.de>
Reviewed-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
Diffstat (limited to 'net/ipv6')
-rw-r--r-- | net/ipv6/xfrm6_output.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/net/ipv6/xfrm6_output.c b/net/ipv6/xfrm6_output.c index 2b663d2ffdcd..455fbf3b91cf 100644 --- a/net/ipv6/xfrm6_output.c +++ b/net/ipv6/xfrm6_output.c | |||
@@ -122,11 +122,28 @@ int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb) | |||
122 | return xfrm_output(sk, skb); | 122 | return xfrm_output(sk, skb); |
123 | } | 123 | } |
124 | 124 | ||
125 | static int __xfrm6_output_state_finish(struct xfrm_state *x, struct sock *sk, | ||
126 | struct sk_buff *skb) | ||
127 | { | ||
128 | const struct xfrm_state_afinfo *afinfo; | ||
129 | int ret = -EAFNOSUPPORT; | ||
130 | |||
131 | rcu_read_lock(); | ||
132 | afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode->family); | ||
133 | if (likely(afinfo)) | ||
134 | ret = afinfo->output_finish(sk, skb); | ||
135 | else | ||
136 | kfree_skb(skb); | ||
137 | rcu_read_unlock(); | ||
138 | |||
139 | return ret; | ||
140 | } | ||
141 | |||
125 | static int __xfrm6_output_finish(struct net *net, struct sock *sk, struct sk_buff *skb) | 142 | static int __xfrm6_output_finish(struct net *net, struct sock *sk, struct sk_buff *skb) |
126 | { | 143 | { |
127 | struct xfrm_state *x = skb_dst(skb)->xfrm; | 144 | struct xfrm_state *x = skb_dst(skb)->xfrm; |
128 | 145 | ||
129 | return x->outer_mode->afinfo->output_finish(sk, skb); | 146 | return __xfrm6_output_state_finish(x, sk, skb); |
130 | } | 147 | } |
131 | 148 | ||
132 | static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | 149 | static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) |
@@ -168,7 +185,7 @@ static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | |||
168 | __xfrm6_output_finish); | 185 | __xfrm6_output_finish); |
169 | 186 | ||
170 | skip_frag: | 187 | skip_frag: |
171 | return x->outer_mode->afinfo->output_finish(sk, skb); | 188 | return __xfrm6_output_state_finish(x, sk, skb); |
172 | } | 189 | } |
173 | 190 | ||
174 | int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) | 191 | int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) |