Skip to content

Commit fddb231

Browse files
Tom Herbertdavem330
authored andcommitted
ila: Add a hook type for LWT routes
In LWT tunnels both an input and output route method is defined. If both of these are executed in the same path then double translation happens and the effect is not correct. This patch adds a new attribute that indicates the hook type. Two values are defined for route output and route output. ILA translation is only done for the one that is set. The default is to enable ILA on route output. Signed-off-by: Tom Herbert <tom@quantonium.net> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 70d5aef commit fddb231

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

include/uapi/linux/ila.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ enum {
1818
ILA_ATTR_PAD,
1919
ILA_ATTR_CSUM_MODE, /* u8 */
2020
ILA_ATTR_IDENT_TYPE, /* u8 */
21+
ILA_ATTR_HOOK_TYPE, /* u8 */
2122

2223
__ILA_ATTR_MAX,
2324
};
@@ -57,4 +58,10 @@ enum {
5758

5859
ILA_ATYPE_USE_FORMAT = 32, /* Get type from type field in identifier */
5960
};
61+
62+
enum {
63+
ILA_HOOK_ROUTE_OUTPUT,
64+
ILA_HOOK_ROUTE_INPUT,
65+
};
66+
6067
#endif /* _UAPI_LINUX_ILA_H */

net/ipv6/ila/ila_lwt.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ struct ila_lwt {
2020
struct ila_params p;
2121
struct dst_cache dst_cache;
2222
u32 connected : 1;
23+
u32 lwt_output : 1;
2324
};
2425

2526
static inline struct ila_lwt *ila_lwt_lwtunnel(
@@ -45,8 +46,10 @@ static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
4546
if (skb->protocol != htons(ETH_P_IPV6))
4647
goto drop;
4748

48-
ila_update_ipv6_locator(skb, ila_params_lwtunnel(orig_dst->lwtstate),
49-
true);
49+
if (ilwt->lwt_output)
50+
ila_update_ipv6_locator(skb,
51+
ila_params_lwtunnel(orig_dst->lwtstate),
52+
true);
5053

5154
if (rt->rt6i_flags & (RTF_GATEWAY | RTF_CACHE)) {
5255
/* Already have a next hop address in route, no need for
@@ -98,11 +101,15 @@ static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
98101
static int ila_input(struct sk_buff *skb)
99102
{
100103
struct dst_entry *dst = skb_dst(skb);
104+
struct ila_lwt *ilwt = ila_lwt_lwtunnel(dst->lwtstate);
101105

102106
if (skb->protocol != htons(ETH_P_IPV6))
103107
goto drop;
104108

105-
ila_update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate), false);
109+
if (!ilwt->lwt_output)
110+
ila_update_ipv6_locator(skb,
111+
ila_params_lwtunnel(dst->lwtstate),
112+
false);
106113

107114
return dst->lwtstate->orig_input(skb);
108115

@@ -115,6 +122,7 @@ static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
115122
[ILA_ATTR_LOCATOR] = { .type = NLA_U64, },
116123
[ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, },
117124
[ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, },
125+
[ILA_ATTR_HOOK_TYPE] = { .type = NLA_U8, },
118126
};
119127

120128
static int ila_build_state(struct nlattr *nla,
@@ -129,7 +137,9 @@ static int ila_build_state(struct nlattr *nla,
129137
const struct fib6_config *cfg6 = cfg;
130138
struct ila_addr *iaddr;
131139
u8 ident_type = ILA_ATYPE_USE_FORMAT;
140+
u8 hook_type = ILA_HOOK_ROUTE_OUTPUT;
132141
u8 csum_mode = ILA_CSUM_NO_ACTION;
142+
bool lwt_output = true;
133143
u8 eff_ident_type;
134144
int ret;
135145

@@ -180,6 +190,20 @@ static int ila_build_state(struct nlattr *nla,
180190
return -EINVAL;
181191
}
182192

193+
if (tb[ILA_ATTR_HOOK_TYPE])
194+
hook_type = nla_get_u8(tb[ILA_ATTR_HOOK_TYPE]);
195+
196+
switch (hook_type) {
197+
case ILA_HOOK_ROUTE_OUTPUT:
198+
lwt_output = true;
199+
break;
200+
case ILA_HOOK_ROUTE_INPUT:
201+
lwt_output = false;
202+
break;
203+
default:
204+
return -EINVAL;
205+
}
206+
183207
if (tb[ILA_ATTR_CSUM_MODE])
184208
csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]);
185209

@@ -202,6 +226,8 @@ static int ila_build_state(struct nlattr *nla,
202226
return ret;
203227
}
204228

229+
ilwt->lwt_output = !!lwt_output;
230+
205231
p = ila_params_lwtunnel(newts);
206232

207233
p->csum_mode = csum_mode;
@@ -236,6 +262,7 @@ static int ila_fill_encap_info(struct sk_buff *skb,
236262
struct lwtunnel_state *lwtstate)
237263
{
238264
struct ila_params *p = ila_params_lwtunnel(lwtstate);
265+
struct ila_lwt *ilwt = ila_lwt_lwtunnel(lwtstate);
239266

240267
if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator.v64,
241268
ILA_ATTR_PAD))
@@ -247,6 +274,11 @@ static int ila_fill_encap_info(struct sk_buff *skb,
247274
if (nla_put_u8(skb, ILA_ATTR_IDENT_TYPE, (__force u8)p->ident_type))
248275
goto nla_put_failure;
249276

277+
if (nla_put_u8(skb, ILA_ATTR_HOOK_TYPE,
278+
ilwt->lwt_output ? ILA_HOOK_ROUTE_OUTPUT :
279+
ILA_HOOK_ROUTE_INPUT))
280+
goto nla_put_failure;
281+
250282
return 0;
251283

252284
nla_put_failure:
@@ -258,6 +290,7 @@ static int ila_encap_nlsize(struct lwtunnel_state *lwtstate)
258290
return nla_total_size_64bit(sizeof(u64)) + /* ILA_ATTR_LOCATOR */
259291
nla_total_size(sizeof(u8)) + /* ILA_ATTR_CSUM_MODE */
260292
nla_total_size(sizeof(u8)) + /* ILA_ATTR_IDENT_TYPE */
293+
nla_total_size(sizeof(u8)) + /* ILA_ATTR_HOOK_TYPE */
261294
0;
262295
}
263296

0 commit comments

Comments
 (0)