seg6: Extend seg6_lookup_any_nexthop() with an oif argument
seg6_lookup_any_nexthop() is called by the different endpoint behaviors (e.g., End, End.X) to resolve an IPv6 route. Extend the function with an output interface argument so that it could be used to resolve a route with a certain output interface. This will be used by subsequent patches that will extend the End.X behavior with an output interface as an optional argument. ip6_route_input_lookup() cannot be used when an output interface is specified as it ignores this parameter. Similarly, calling ip6_pol_route() when a table ID was not specified (e.g., End.X behavior) is wrong. Therefore, when an output interface is specified without a table ID, resolve the route using ip6_route_output() which will take the output interface into account. Note that no endpoint behavior currently passes both a table ID and an output interface, so the oif argument passed to ip6_pol_route() is always zero and there are no functional changes in this regard. Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Andrea Mayer <andrea.mayer@uniroma2.it> Link: https://patch.msgid.link/20250612122323.584113-2-idosch@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
0550890b2f
commit
01c411238c
+10
-7
@@ -270,7 +270,7 @@ static void advance_nextseg(struct ipv6_sr_hdr *srh, struct in6_addr *daddr)
|
|||||||
|
|
||||||
static int
|
static int
|
||||||
seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
|
seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
|
||||||
u32 tbl_id, bool local_delivery)
|
u32 tbl_id, bool local_delivery, int oif)
|
||||||
{
|
{
|
||||||
struct net *net = dev_net(skb->dev);
|
struct net *net = dev_net(skb->dev);
|
||||||
struct ipv6hdr *hdr = ipv6_hdr(skb);
|
struct ipv6hdr *hdr = ipv6_hdr(skb);
|
||||||
@@ -282,6 +282,7 @@ seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
|
|||||||
|
|
||||||
memset(&fl6, 0, sizeof(fl6));
|
memset(&fl6, 0, sizeof(fl6));
|
||||||
fl6.flowi6_iif = skb->dev->ifindex;
|
fl6.flowi6_iif = skb->dev->ifindex;
|
||||||
|
fl6.flowi6_oif = oif;
|
||||||
fl6.daddr = nhaddr ? *nhaddr : hdr->daddr;
|
fl6.daddr = nhaddr ? *nhaddr : hdr->daddr;
|
||||||
fl6.saddr = hdr->saddr;
|
fl6.saddr = hdr->saddr;
|
||||||
fl6.flowlabel = ip6_flowinfo(hdr);
|
fl6.flowlabel = ip6_flowinfo(hdr);
|
||||||
@@ -291,17 +292,19 @@ seg6_lookup_any_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr,
|
|||||||
if (nhaddr)
|
if (nhaddr)
|
||||||
fl6.flowi6_flags = FLOWI_FLAG_KNOWN_NH;
|
fl6.flowi6_flags = FLOWI_FLAG_KNOWN_NH;
|
||||||
|
|
||||||
if (!tbl_id) {
|
if (!tbl_id && !oif) {
|
||||||
dst = ip6_route_input_lookup(net, skb->dev, &fl6, skb, flags);
|
dst = ip6_route_input_lookup(net, skb->dev, &fl6, skb, flags);
|
||||||
} else {
|
} else if (tbl_id) {
|
||||||
struct fib6_table *table;
|
struct fib6_table *table;
|
||||||
|
|
||||||
table = fib6_get_table(net, tbl_id);
|
table = fib6_get_table(net, tbl_id);
|
||||||
if (!table)
|
if (!table)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
rt = ip6_pol_route(net, table, 0, &fl6, skb, flags);
|
rt = ip6_pol_route(net, table, oif, &fl6, skb, flags);
|
||||||
dst = &rt->dst;
|
dst = &rt->dst;
|
||||||
|
} else {
|
||||||
|
dst = ip6_route_output(net, NULL, &fl6);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* we want to discard traffic destined for local packet processing,
|
/* we want to discard traffic destined for local packet processing,
|
||||||
@@ -330,7 +333,7 @@ out:
|
|||||||
int seg6_lookup_nexthop(struct sk_buff *skb,
|
int seg6_lookup_nexthop(struct sk_buff *skb,
|
||||||
struct in6_addr *nhaddr, u32 tbl_id)
|
struct in6_addr *nhaddr, u32 tbl_id)
|
||||||
{
|
{
|
||||||
return seg6_lookup_any_nexthop(skb, nhaddr, tbl_id, false);
|
return seg6_lookup_any_nexthop(skb, nhaddr, tbl_id, false, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static __u8 seg6_flv_lcblock_octects(const struct seg6_flavors_info *finfo)
|
static __u8 seg6_flv_lcblock_octects(const struct seg6_flavors_info *finfo)
|
||||||
@@ -1277,7 +1280,7 @@ static int input_action_end_dt6(struct sk_buff *skb,
|
|||||||
/* note: this time we do not need to specify the table because the VRF
|
/* note: this time we do not need to specify the table because the VRF
|
||||||
* takes care of selecting the correct table.
|
* takes care of selecting the correct table.
|
||||||
*/
|
*/
|
||||||
seg6_lookup_any_nexthop(skb, NULL, 0, true);
|
seg6_lookup_any_nexthop(skb, NULL, 0, true, 0);
|
||||||
|
|
||||||
return dst_input(skb);
|
return dst_input(skb);
|
||||||
|
|
||||||
@@ -1285,7 +1288,7 @@ legacy_mode:
|
|||||||
#endif
|
#endif
|
||||||
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
|
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
|
||||||
|
|
||||||
seg6_lookup_any_nexthop(skb, NULL, slwt->table, true);
|
seg6_lookup_any_nexthop(skb, NULL, slwt->table, true, 0);
|
||||||
|
|
||||||
return dst_input(skb);
|
return dst_input(skb);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user