@@ -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
2526static 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)
98101static 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
120128static 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
252284nla_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