aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorTom Herbert <tom@herbertland.com>2015-08-17 16:42:24 -0400
committerDavid S. Miller <davem@davemloft.net>2015-08-18 00:33:05 -0400
commit2536862311d2276454ddef9dc36d6551a4b400fd (patch)
tree7be7caf4f95bdd2c50749dc2d42319acbc250030 /net/core
parentf376d4adfdd2d860aea3e99aa86e98324621ece7 (diff)
lwt: Add support to redirect dst.input
This patch adds the capability to redirect dst input in the same way that dst output is redirected by LWT. Also, save the original dst.input and and dst.out when setting up lwtunnel redirection. These can be called by the client as a pass- through. Signed-off-by: Tom Herbert <tom@herbertland.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/lwtunnel.c55
1 files changed, 55 insertions, 0 deletions
diff --git a/net/core/lwtunnel.c b/net/core/lwtunnel.c
index 5d6d8e3d450a..3331585174d9 100644
--- a/net/core/lwtunnel.c
+++ b/net/core/lwtunnel.c
@@ -241,3 +241,58 @@ int lwtunnel_output(struct sock *sk, struct sk_buff *skb)
241 return __lwtunnel_output(sk, skb, lwtstate); 241 return __lwtunnel_output(sk, skb, lwtstate);
242} 242}
243EXPORT_SYMBOL(lwtunnel_output); 243EXPORT_SYMBOL(lwtunnel_output);
244
245int __lwtunnel_input(struct sk_buff *skb,
246 struct lwtunnel_state *lwtstate)
247{
248 const struct lwtunnel_encap_ops *ops;
249 int ret = -EINVAL;
250
251 if (!lwtstate)
252 goto drop;
253
254 if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
255 lwtstate->type > LWTUNNEL_ENCAP_MAX)
256 return 0;
257
258 ret = -EOPNOTSUPP;
259 rcu_read_lock();
260 ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
261 if (likely(ops && ops->input))
262 ret = ops->input(skb);
263 rcu_read_unlock();
264
265 if (ret == -EOPNOTSUPP)
266 goto drop;
267
268 return ret;
269
270drop:
271 kfree_skb(skb);
272
273 return ret;
274}
275
276int lwtunnel_input6(struct sk_buff *skb)
277{
278 struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
279 struct lwtunnel_state *lwtstate = NULL;
280
281 if (rt)
282 lwtstate = rt->rt6i_lwtstate;
283
284 return __lwtunnel_input(skb, lwtstate);
285}
286EXPORT_SYMBOL(lwtunnel_input6);
287
288int lwtunnel_input(struct sk_buff *skb)
289{
290 struct rtable *rt = (struct rtable *)skb_dst(skb);
291 struct lwtunnel_state *lwtstate = NULL;
292
293 if (rt)
294 lwtstate = rt->rt_lwtstate;
295
296 return __lwtunnel_input(skb, lwtstate);
297}
298EXPORT_SYMBOL(lwtunnel_input);