mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-28 10:41:38 -04:00
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
This commit is contained in:
parent
f376d4adfd
commit
2536862311
4 changed files with 98 additions and 3 deletions
|
|
@ -241,3 +241,58 @@ int lwtunnel_output(struct sock *sk, struct sk_buff *skb)
|
|||
return __lwtunnel_output(sk, skb, lwtstate);
|
||||
}
|
||||
EXPORT_SYMBOL(lwtunnel_output);
|
||||
|
||||
int __lwtunnel_input(struct sk_buff *skb,
|
||||
struct lwtunnel_state *lwtstate)
|
||||
{
|
||||
const struct lwtunnel_encap_ops *ops;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!lwtstate)
|
||||
goto drop;
|
||||
|
||||
if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
|
||||
lwtstate->type > LWTUNNEL_ENCAP_MAX)
|
||||
return 0;
|
||||
|
||||
ret = -EOPNOTSUPP;
|
||||
rcu_read_lock();
|
||||
ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
|
||||
if (likely(ops && ops->input))
|
||||
ret = ops->input(skb);
|
||||
rcu_read_unlock();
|
||||
|
||||
if (ret == -EOPNOTSUPP)
|
||||
goto drop;
|
||||
|
||||
return ret;
|
||||
|
||||
drop:
|
||||
kfree_skb(skb);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int lwtunnel_input6(struct sk_buff *skb)
|
||||
{
|
||||
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
|
||||
struct lwtunnel_state *lwtstate = NULL;
|
||||
|
||||
if (rt)
|
||||
lwtstate = rt->rt6i_lwtstate;
|
||||
|
||||
return __lwtunnel_input(skb, lwtstate);
|
||||
}
|
||||
EXPORT_SYMBOL(lwtunnel_input6);
|
||||
|
||||
int lwtunnel_input(struct sk_buff *skb)
|
||||
{
|
||||
struct rtable *rt = (struct rtable *)skb_dst(skb);
|
||||
struct lwtunnel_state *lwtstate = NULL;
|
||||
|
||||
if (rt)
|
||||
lwtstate = rt->rt_lwtstate;
|
||||
|
||||
return __lwtunnel_input(skb, lwtstate);
|
||||
}
|
||||
EXPORT_SYMBOL(lwtunnel_input);
|
||||
|
|
|
|||
|
|
@ -1631,8 +1631,14 @@ static int __mkroute_input(struct sk_buff *skb,
|
|||
rth->dst.output = ip_output;
|
||||
|
||||
rt_set_nexthop(rth, daddr, res, fnhe, res->fi, res->type, itag);
|
||||
if (lwtunnel_output_redirect(rth->rt_lwtstate))
|
||||
if (lwtunnel_output_redirect(rth->rt_lwtstate)) {
|
||||
rth->rt_lwtstate->orig_output = rth->dst.output;
|
||||
rth->dst.output = lwtunnel_output;
|
||||
}
|
||||
if (lwtunnel_input_redirect(rth->rt_lwtstate)) {
|
||||
rth->rt_lwtstate->orig_input = rth->dst.input;
|
||||
rth->dst.input = lwtunnel_input;
|
||||
}
|
||||
skb_dst_set(skb, &rth->dst);
|
||||
out:
|
||||
err = 0;
|
||||
|
|
|
|||
|
|
@ -1785,8 +1785,14 @@ int ip6_route_add(struct fib6_config *cfg)
|
|||
if (err)
|
||||
goto out;
|
||||
rt->rt6i_lwtstate = lwtstate_get(lwtstate);
|
||||
if (lwtunnel_output_redirect(rt->rt6i_lwtstate))
|
||||
if (lwtunnel_output_redirect(rt->rt6i_lwtstate)) {
|
||||
rt->rt6i_lwtstate->orig_output = rt->dst.output;
|
||||
rt->dst.output = lwtunnel_output6;
|
||||
}
|
||||
if (lwtunnel_input_redirect(rt->rt6i_lwtstate)) {
|
||||
rt->rt6i_lwtstate->orig_input = rt->dst.input;
|
||||
rt->dst.input = lwtunnel_input6;
|
||||
}
|
||||
}
|
||||
|
||||
ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len);
|
||||
|
|
|
|||
Loading…
Reference in a new issue