@@ -270,7 +270,7 @@ static void advance_nextseg(struct ipv6_sr_hdr *srh, struct in6_addr *daddr)
270270
271271static int
272272seg6_lookup_any_nexthop (struct sk_buff * skb , struct in6_addr * nhaddr ,
273- u32 tbl_id , bool local_delivery )
273+ u32 tbl_id , bool local_delivery , int oif )
274274{
275275 struct net * net = dev_net (skb -> dev );
276276 struct ipv6hdr * hdr = ipv6_hdr (skb );
@@ -282,6 +282,7 @@ seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
282282
283283 memset (& fl6 , 0 , sizeof (fl6 ));
284284 fl6 .flowi6_iif = skb -> dev -> ifindex ;
285+ fl6 .flowi6_oif = oif ;
285286 fl6 .daddr = nhaddr ? * nhaddr : hdr -> daddr ;
286287 fl6 .saddr = hdr -> saddr ;
287288 fl6 .flowlabel = ip6_flowinfo (hdr );
@@ -291,17 +292,19 @@ seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
291292 if (nhaddr )
292293 fl6 .flowi6_flags = FLOWI_FLAG_KNOWN_NH ;
293294
294- if (!tbl_id ) {
295+ if (!tbl_id && ! oif ) {
295296 dst = ip6_route_input_lookup (net , skb -> dev , & fl6 , skb , flags );
296- } else {
297+ } else if ( tbl_id ) {
297298 struct fib6_table * table ;
298299
299300 table = fib6_get_table (net , tbl_id );
300301 if (!table )
301302 goto out ;
302303
303- rt = ip6_pol_route (net , table , 0 , & fl6 , skb , flags );
304+ rt = ip6_pol_route (net , table , oif , & fl6 , skb , flags );
304305 dst = & rt -> dst ;
306+ } else {
307+ dst = ip6_route_output (net , NULL , & fl6 );
305308 }
306309
307310 /* we want to discard traffic destined for local packet processing,
@@ -330,7 +333,7 @@ seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
330333int seg6_lookup_nexthop (struct sk_buff * skb ,
331334 struct in6_addr * nhaddr , u32 tbl_id )
332335{
333- return seg6_lookup_any_nexthop (skb , nhaddr , tbl_id , false);
336+ return seg6_lookup_any_nexthop (skb , nhaddr , tbl_id , false, 0 );
334337}
335338
336339static __u8 seg6_flv_lcblock_octects (const struct seg6_flavors_info * finfo )
@@ -418,7 +421,7 @@ static int end_next_csid_core(struct sk_buff *skb, struct seg6_local_lwt *slwt)
418421static int input_action_end_x_finish (struct sk_buff * skb ,
419422 struct seg6_local_lwt * slwt )
420423{
421- seg6_lookup_nexthop (skb , & slwt -> nh6 , 0 );
424+ seg6_lookup_any_nexthop (skb , & slwt -> nh6 , 0 , false, slwt -> oif );
422425
423426 return dst_input (skb );
424427}
@@ -1277,15 +1280,15 @@ static int input_action_end_dt6(struct sk_buff *skb,
12771280 /* note: this time we do not need to specify the table because the VRF
12781281 * takes care of selecting the correct table.
12791282 */
1280- seg6_lookup_any_nexthop (skb , NULL , 0 , true);
1283+ seg6_lookup_any_nexthop (skb , NULL , 0 , true, 0 );
12811284
12821285 return dst_input (skb );
12831286
12841287legacy_mode :
12851288#endif
12861289 skb_set_transport_header (skb , sizeof (struct ipv6hdr ));
12871290
1288- seg6_lookup_any_nexthop (skb , NULL , slwt -> table , true);
1291+ seg6_lookup_any_nexthop (skb , NULL , slwt -> table , true, 0 );
12891292
12901293 return dst_input (skb );
12911294
@@ -1477,7 +1480,8 @@ static struct seg6_action_desc seg6_action_table[] = {
14771480 .action = SEG6_LOCAL_ACTION_END_X ,
14781481 .attrs = SEG6_F_ATTR (SEG6_LOCAL_NH6 ),
14791482 .optattrs = SEG6_F_LOCAL_COUNTERS |
1480- SEG6_F_LOCAL_FLAVORS ,
1483+ SEG6_F_LOCAL_FLAVORS |
1484+ SEG6_F_ATTR (SEG6_LOCAL_OIF ),
14811485 .input = input_action_end_x ,
14821486 },
14831487 {
0 commit comments