Skip to content

Commit ffce419

Browse files
roopa-prabhudavem330
authored andcommitted
lwtunnel: support dst output redirect function
This patch introduces lwtunnel_output function to call corresponding lwtunnels output function to xmit the packet. It adds two variants lwtunnel_output and lwtunnel_output6 for ipv4 and ipv6 respectively today. But this is subject to change when lwtstate will reside in dst or dst_metadata (as per upstream discussions). Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 19e42e4 commit ffce419

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

include/net/lwtunnel.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ int lwtunnel_fill_encap(struct sk_buff *skb,
6969
int lwtunnel_get_encap_size(struct lwtunnel_state *lwtstate);
7070
struct lwtunnel_state *lwtunnel_state_alloc(int hdr_len);
7171
int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b);
72+
int lwtunnel_output(struct sock *sk, struct sk_buff *skb);
73+
int lwtunnel_output6(struct sock *sk, struct sk_buff *skb);
7274

7375
#else
7476

@@ -127,6 +129,16 @@ static inline int lwtunnel_cmp_encap(struct lwtunnel_state *a,
127129
return 0;
128130
}
129131

132+
static inline int lwtunnel_output(struct sock *sk, struct sk_buff *skb)
133+
{
134+
return -EOPNOTSUPP;
135+
}
136+
137+
static inline int lwtunnel_output6(struct sock *sk, struct sk_buff *skb)
138+
{
139+
return -EOPNOTSUPP;
140+
}
141+
130142
#endif
131143

132144
#endif /* __NET_LWTUNNEL_H */

net/core/lwtunnel.c

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include <net/lwtunnel.h>
2727
#include <net/rtnetlink.h>
28+
#include <net/ip6_fib.h>
2829

2930
struct lwtunnel_state *lwtunnel_state_alloc(int encap_len)
3031
{
@@ -177,3 +178,58 @@ int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b)
177178
return ret;
178179
}
179180
EXPORT_SYMBOL(lwtunnel_cmp_encap);
181+
182+
int __lwtunnel_output(struct sock *sk, struct sk_buff *skb,
183+
struct lwtunnel_state *lwtstate)
184+
{
185+
const struct lwtunnel_encap_ops *ops;
186+
int ret = -EINVAL;
187+
188+
if (!lwtstate)
189+
goto drop;
190+
191+
if (lwtstate->type == LWTUNNEL_ENCAP_NONE ||
192+
lwtstate->type > LWTUNNEL_ENCAP_MAX)
193+
return 0;
194+
195+
ret = -EOPNOTSUPP;
196+
rcu_read_lock();
197+
ops = rcu_dereference(lwtun_encaps[lwtstate->type]);
198+
if (likely(ops && ops->output))
199+
ret = ops->output(sk, skb);
200+
rcu_read_unlock();
201+
202+
if (ret == -EOPNOTSUPP)
203+
goto drop;
204+
205+
return ret;
206+
207+
drop:
208+
kfree(skb);
209+
210+
return ret;
211+
}
212+
213+
int lwtunnel_output6(struct sock *sk, struct sk_buff *skb)
214+
{
215+
struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
216+
struct lwtunnel_state *lwtstate = NULL;
217+
218+
if (rt)
219+
lwtstate = rt->rt6i_lwtstate;
220+
221+
return __lwtunnel_output(sk, skb, lwtstate);
222+
}
223+
EXPORT_SYMBOL(lwtunnel_output6);
224+
225+
int lwtunnel_output(struct sock *sk, struct sk_buff *skb)
226+
{
227+
struct rtable *rt = (struct rtable *)skb_dst(skb);
228+
struct lwtunnel_state *lwtstate = NULL;
229+
230+
if (rt)
231+
lwtstate = rt->rt_lwtstate;
232+
233+
return __lwtunnel_output(sk, skb, lwtstate);
234+
}
235+
EXPORT_SYMBOL(lwtunnel_output);

0 commit comments

Comments
 (0)