Commit fddb231e authored by Tom Herbert's avatar Tom Herbert Committed by David S. Miller

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: default avatarTom Herbert <tom@quantonium.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 70d5aef4
...@@ -18,6 +18,7 @@ enum { ...@@ -18,6 +18,7 @@ enum {
ILA_ATTR_PAD, ILA_ATTR_PAD,
ILA_ATTR_CSUM_MODE, /* u8 */ ILA_ATTR_CSUM_MODE, /* u8 */
ILA_ATTR_IDENT_TYPE, /* u8 */ ILA_ATTR_IDENT_TYPE, /* u8 */
ILA_ATTR_HOOK_TYPE, /* u8 */
__ILA_ATTR_MAX, __ILA_ATTR_MAX,
}; };
...@@ -57,4 +58,10 @@ enum { ...@@ -57,4 +58,10 @@ enum {
ILA_ATYPE_USE_FORMAT = 32, /* Get type from type field in identifier */ ILA_ATYPE_USE_FORMAT = 32, /* Get type from type field in identifier */
}; };
enum {
ILA_HOOK_ROUTE_OUTPUT,
ILA_HOOK_ROUTE_INPUT,
};
#endif /* _UAPI_LINUX_ILA_H */ #endif /* _UAPI_LINUX_ILA_H */
...@@ -20,6 +20,7 @@ struct ila_lwt { ...@@ -20,6 +20,7 @@ struct ila_lwt {
struct ila_params p; struct ila_params p;
struct dst_cache dst_cache; struct dst_cache dst_cache;
u32 connected : 1; u32 connected : 1;
u32 lwt_output : 1;
}; };
static inline struct ila_lwt *ila_lwt_lwtunnel( 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) ...@@ -45,8 +46,10 @@ static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
if (skb->protocol != htons(ETH_P_IPV6)) if (skb->protocol != htons(ETH_P_IPV6))
goto drop; goto drop;
ila_update_ipv6_locator(skb, ila_params_lwtunnel(orig_dst->lwtstate), if (ilwt->lwt_output)
true); ila_update_ipv6_locator(skb,
ila_params_lwtunnel(orig_dst->lwtstate),
true);
if (rt->rt6i_flags & (RTF_GATEWAY | RTF_CACHE)) { if (rt->rt6i_flags & (RTF_GATEWAY | RTF_CACHE)) {
/* Already have a next hop address in route, no need for /* 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) ...@@ -98,11 +101,15 @@ static int ila_output(struct net *net, struct sock *sk, struct sk_buff *skb)
static int ila_input(struct sk_buff *skb) static int ila_input(struct sk_buff *skb)
{ {
struct dst_entry *dst = skb_dst(skb); struct dst_entry *dst = skb_dst(skb);
struct ila_lwt *ilwt = ila_lwt_lwtunnel(dst->lwtstate);
if (skb->protocol != htons(ETH_P_IPV6)) if (skb->protocol != htons(ETH_P_IPV6))
goto drop; goto drop;
ila_update_ipv6_locator(skb, ila_params_lwtunnel(dst->lwtstate), false); if (!ilwt->lwt_output)
ila_update_ipv6_locator(skb,
ila_params_lwtunnel(dst->lwtstate),
false);
return dst->lwtstate->orig_input(skb); return dst->lwtstate->orig_input(skb);
...@@ -115,6 +122,7 @@ static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = { ...@@ -115,6 +122,7 @@ static const struct nla_policy ila_nl_policy[ILA_ATTR_MAX + 1] = {
[ILA_ATTR_LOCATOR] = { .type = NLA_U64, }, [ILA_ATTR_LOCATOR] = { .type = NLA_U64, },
[ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, }, [ILA_ATTR_CSUM_MODE] = { .type = NLA_U8, },
[ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, }, [ILA_ATTR_IDENT_TYPE] = { .type = NLA_U8, },
[ILA_ATTR_HOOK_TYPE] = { .type = NLA_U8, },
}; };
static int ila_build_state(struct nlattr *nla, static int ila_build_state(struct nlattr *nla,
...@@ -129,7 +137,9 @@ static int ila_build_state(struct nlattr *nla, ...@@ -129,7 +137,9 @@ static int ila_build_state(struct nlattr *nla,
const struct fib6_config *cfg6 = cfg; const struct fib6_config *cfg6 = cfg;
struct ila_addr *iaddr; struct ila_addr *iaddr;
u8 ident_type = ILA_ATYPE_USE_FORMAT; u8 ident_type = ILA_ATYPE_USE_FORMAT;
u8 hook_type = ILA_HOOK_ROUTE_OUTPUT;
u8 csum_mode = ILA_CSUM_NO_ACTION; u8 csum_mode = ILA_CSUM_NO_ACTION;
bool lwt_output = true;
u8 eff_ident_type; u8 eff_ident_type;
int ret; int ret;
...@@ -180,6 +190,20 @@ static int ila_build_state(struct nlattr *nla, ...@@ -180,6 +190,20 @@ static int ila_build_state(struct nlattr *nla,
return -EINVAL; return -EINVAL;
} }
if (tb[ILA_ATTR_HOOK_TYPE])
hook_type = nla_get_u8(tb[ILA_ATTR_HOOK_TYPE]);
switch (hook_type) {
case ILA_HOOK_ROUTE_OUTPUT:
lwt_output = true;
break;
case ILA_HOOK_ROUTE_INPUT:
lwt_output = false;
break;
default:
return -EINVAL;
}
if (tb[ILA_ATTR_CSUM_MODE]) if (tb[ILA_ATTR_CSUM_MODE])
csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]); csum_mode = nla_get_u8(tb[ILA_ATTR_CSUM_MODE]);
...@@ -202,6 +226,8 @@ static int ila_build_state(struct nlattr *nla, ...@@ -202,6 +226,8 @@ static int ila_build_state(struct nlattr *nla,
return ret; return ret;
} }
ilwt->lwt_output = !!lwt_output;
p = ila_params_lwtunnel(newts); p = ila_params_lwtunnel(newts);
p->csum_mode = csum_mode; p->csum_mode = csum_mode;
...@@ -236,6 +262,7 @@ static int ila_fill_encap_info(struct sk_buff *skb, ...@@ -236,6 +262,7 @@ static int ila_fill_encap_info(struct sk_buff *skb,
struct lwtunnel_state *lwtstate) struct lwtunnel_state *lwtstate)
{ {
struct ila_params *p = ila_params_lwtunnel(lwtstate); struct ila_params *p = ila_params_lwtunnel(lwtstate);
struct ila_lwt *ilwt = ila_lwt_lwtunnel(lwtstate);
if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator.v64, if (nla_put_u64_64bit(skb, ILA_ATTR_LOCATOR, (__force u64)p->locator.v64,
ILA_ATTR_PAD)) ILA_ATTR_PAD))
...@@ -247,6 +274,11 @@ static int ila_fill_encap_info(struct sk_buff *skb, ...@@ -247,6 +274,11 @@ static int ila_fill_encap_info(struct sk_buff *skb,
if (nla_put_u8(skb, ILA_ATTR_IDENT_TYPE, (__force u8)p->ident_type)) if (nla_put_u8(skb, ILA_ATTR_IDENT_TYPE, (__force u8)p->ident_type))
goto nla_put_failure; goto nla_put_failure;
if (nla_put_u8(skb, ILA_ATTR_HOOK_TYPE,
ilwt->lwt_output ? ILA_HOOK_ROUTE_OUTPUT :
ILA_HOOK_ROUTE_INPUT))
goto nla_put_failure;
return 0; return 0;
nla_put_failure: nla_put_failure:
...@@ -258,6 +290,7 @@ static int ila_encap_nlsize(struct lwtunnel_state *lwtstate) ...@@ -258,6 +290,7 @@ static int ila_encap_nlsize(struct lwtunnel_state *lwtstate)
return nla_total_size_64bit(sizeof(u64)) + /* ILA_ATTR_LOCATOR */ return nla_total_size_64bit(sizeof(u64)) + /* ILA_ATTR_LOCATOR */
nla_total_size(sizeof(u8)) + /* ILA_ATTR_CSUM_MODE */ nla_total_size(sizeof(u8)) + /* ILA_ATTR_CSUM_MODE */
nla_total_size(sizeof(u8)) + /* ILA_ATTR_IDENT_TYPE */ nla_total_size(sizeof(u8)) + /* ILA_ATTR_IDENT_TYPE */
nla_total_size(sizeof(u8)) + /* ILA_ATTR_HOOK_TYPE */
0; 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment