|
25 | 25 |
|
26 | 26 | #include <net/lwtunnel.h>
|
27 | 27 | #include <net/rtnetlink.h>
|
| 28 | +#include <net/ip6_fib.h> |
28 | 29 |
|
29 | 30 | struct lwtunnel_state *lwtunnel_state_alloc(int encap_len)
|
30 | 31 | {
|
@@ -177,3 +178,58 @@ int lwtunnel_cmp_encap(struct lwtunnel_state *a, struct lwtunnel_state *b)
|
177 | 178 | return ret;
|
178 | 179 | }
|
179 | 180 | 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