@@ -270,7 +270,7 @@ static void advance_nextseg(struct ipv6_sr_hdr *srh, struct in6_addr *daddr)
270
270
271
271
static int
272
272
seg6_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 )
274
274
{
275
275
struct net * net = dev_net (skb -> dev );
276
276
struct ipv6hdr * hdr = ipv6_hdr (skb );
@@ -282,6 +282,7 @@ seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
282
282
283
283
memset (& fl6 , 0 , sizeof (fl6 ));
284
284
fl6 .flowi6_iif = skb -> dev -> ifindex ;
285
+ fl6 .flowi6_oif = oif ;
285
286
fl6 .daddr = nhaddr ? * nhaddr : hdr -> daddr ;
286
287
fl6 .saddr = hdr -> saddr ;
287
288
fl6 .flowlabel = ip6_flowinfo (hdr );
@@ -291,17 +292,19 @@ seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
291
292
if (nhaddr )
292
293
fl6 .flowi6_flags = FLOWI_FLAG_KNOWN_NH ;
293
294
294
- if (!tbl_id ) {
295
+ if (!tbl_id && ! oif ) {
295
296
dst = ip6_route_input_lookup (net , skb -> dev , & fl6 , skb , flags );
296
- } else {
297
+ } else if ( tbl_id ) {
297
298
struct fib6_table * table ;
298
299
299
300
table = fib6_get_table (net , tbl_id );
300
301
if (!table )
301
302
goto out ;
302
303
303
- rt = ip6_pol_route (net , table , 0 , & fl6 , skb , flags );
304
+ rt = ip6_pol_route (net , table , oif , & fl6 , skb , flags );
304
305
dst = & rt -> dst ;
306
+ } else {
307
+ dst = ip6_route_output (net , NULL , & fl6 );
305
308
}
306
309
307
310
/* 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,
330
333
int seg6_lookup_nexthop (struct sk_buff * skb ,
331
334
struct in6_addr * nhaddr , u32 tbl_id )
332
335
{
333
- return seg6_lookup_any_nexthop (skb , nhaddr , tbl_id , false);
336
+ return seg6_lookup_any_nexthop (skb , nhaddr , tbl_id , false, 0 );
334
337
}
335
338
336
339
static __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)
418
421
static int input_action_end_x_finish (struct sk_buff * skb ,
419
422
struct seg6_local_lwt * slwt )
420
423
{
421
- seg6_lookup_nexthop (skb , & slwt -> nh6 , 0 );
424
+ seg6_lookup_any_nexthop (skb , & slwt -> nh6 , 0 , false, slwt -> oif );
422
425
423
426
return dst_input (skb );
424
427
}
@@ -1277,15 +1280,15 @@ static int input_action_end_dt6(struct sk_buff *skb,
1277
1280
/* note: this time we do not need to specify the table because the VRF
1278
1281
* takes care of selecting the correct table.
1279
1282
*/
1280
- seg6_lookup_any_nexthop (skb , NULL , 0 , true);
1283
+ seg6_lookup_any_nexthop (skb , NULL , 0 , true, 0 );
1281
1284
1282
1285
return dst_input (skb );
1283
1286
1284
1287
legacy_mode :
1285
1288
#endif
1286
1289
skb_set_transport_header (skb , sizeof (struct ipv6hdr ));
1287
1290
1288
- seg6_lookup_any_nexthop (skb , NULL , slwt -> table , true);
1291
+ seg6_lookup_any_nexthop (skb , NULL , slwt -> table , true, 0 );
1289
1292
1290
1293
return dst_input (skb );
1291
1294
@@ -1477,7 +1480,8 @@ static struct seg6_action_desc seg6_action_table[] = {
1477
1480
.action = SEG6_LOCAL_ACTION_END_X ,
1478
1481
.attrs = SEG6_F_ATTR (SEG6_LOCAL_NH6 ),
1479
1482
.optattrs = SEG6_F_LOCAL_COUNTERS |
1480
- SEG6_F_LOCAL_FLAVORS ,
1483
+ SEG6_F_LOCAL_FLAVORS |
1484
+ SEG6_F_ATTR (SEG6_LOCAL_OIF ),
1481
1485
.input = input_action_end_x ,
1482
1486
},
1483
1487
{
0 commit comments