Skip to content

Commit

Permalink
ip6: ensure no nexthop is created with invalid iface id
Browse files Browse the repository at this point in the history
When applying the following configuration:

grout# add ip6 address fd00:abcd::1/64 iface p0
grout# add ip6 route 2025:666::/64 via fd00:abcd::cafe

We end up with two nexthops created:

grout# show ip6 route
VRF  DESTINATION     NEXT_HOP
0    fd00:abcd::/64  fd00:abcd::1
0    2025:666::/64   fd00:abcd::cafe
grout# show ip6 nexthop
VRF  IP               MAC                IFACE  QUEUE  AGE  STATE
0    fd00:abcd::1     30:3e:a7:0b:ea:78  p0     0      0    reachable static local link
0    fd00:abcd::cafe  ??:??:??:??:??:??  ?      0      ?    gateway

The fd00:abcd::cafe nexthop is created with an undefined interface
whereas it should have p0.

When adding a new route, if the nexthop does not exist yet, make sure to
use the same iface_id than the nexthop result of a route lookup.

Remove the handling of gateway routes that have undefined interface id
in ip6_nexthop_unreachable_cb. This can no longer happen.

Update the IPv6 forwarding test to ensure it works as expected.

Signed-off-by: Robin Jarry <[email protected]>
  • Loading branch information
rjarry authored and christophefontaine committed Jan 22, 2025
1 parent 75286b7 commit 46b14b0
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 8 deletions.
4 changes: 0 additions & 4 deletions modules/ip6/control/nexthop.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,6 @@ void ip6_nexthop_unreachable_cb(struct rte_mbuf *m) {
if (remote == NULL) {
// No existing nexthop for this IP, create one.
remote = ip6_nexthop_new(nh->vrf_id, nh->iface_id, dst);
} else if (remote->flags & GR_NH_F_GATEWAY && remote->iface_id == 0) {
// Gateway route with uninitialized destination.
// Now, we can at least know what is the output interface.
remote->iface_id = nh->iface_id;
}

if (remote == NULL) {
Expand Down
8 changes: 4 additions & 4 deletions modules/ip6/control/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,8 +201,8 @@ int ip6_route_delete(

static struct api_out route6_add(const void *request, void ** /*response*/) {
const struct gr_ip6_route_add_req *req = request;
struct nexthop *nh, *via;
struct rte_fib6 *fib6;
struct nexthop *nh;
int ret;

nh = ip6_route_lookup_exact(
Expand All @@ -214,14 +214,14 @@ static struct api_out route6_add(const void *request, void ** /*response*/) {
return api_out(EEXIST, 0);
}

if (ip6_route_lookup(req->vrf_id, GR_IFACE_ID_UNDEF, &req->nh) == NULL)
if ((via = ip6_route_lookup(req->vrf_id, GR_IFACE_ID_UNDEF, &req->nh)) == NULL)
return api_out(EHOSTUNREACH, 0);

if ((fib6 = get_or_create_fib6(req->vrf_id)) == NULL)
return api_out(errno, 0);

if ((nh = ip6_nexthop_lookup(req->vrf_id, GR_IFACE_ID_UNDEF, &req->nh)) == NULL)
if ((nh = ip6_nexthop_new(req->vrf_id, GR_IFACE_ID_UNDEF, &req->nh)) == NULL)
if ((nh = ip6_nexthop_lookup(req->vrf_id, via->iface_id, &req->nh)) == NULL)
if ((nh = ip6_nexthop_new(req->vrf_id, via->iface_id, &req->nh)) == NULL)
return api_out(errno, 0);

if ((ret = rte_fib6_add(fib6, &req->dest.ip, req->dest.prefixlen, nh_ptr_to_id(nh))) < 0) {
Expand Down
8 changes: 8 additions & 0 deletions smoke/ip6_forward_test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ grcli add interface port $p1 devargs net_tap0,iface=$p1 mac d2:f0:0c:ba:a4:11
grcli add interface port $p2 devargs net_tap1,iface=$p2 mac d2:f0:0c:ba:a4:12
grcli add ip6 address fd00:ba4:1::1/64 iface $p1
grcli add ip6 address fd00:ba4:2::1/64 iface $p2
grcli add ip6 route fd00:f00:1::/64 via fd00:ba4:1::2
grcli add ip6 route fd00:f00:2::/64 via fd00:ba4:2::2

for n in 1 2; do
p=$run_id$n
Expand All @@ -19,7 +21,9 @@ for n in 1 2; do
ip link set $p netns $p
ip -n $p link set $p address d2:ad:ca:ca:a4:1$n
ip -n $p link set $p up
ip -n $p link set lo up
ip -n $p addr add fd00:ba4:$n::2/64 dev $p
ip -n $p addr add fd00:f00:$n::2/64 dev lo
ip -n $p route add default via fd00:ba4:$n::1
ip -n $p addr show
done
Expand All @@ -28,9 +32,13 @@ sleep 3 # wait for DAD

ip netns exec $p1 ping6 -i0.01 -c3 fe80::d2f0:cff:feba:a411
ip netns exec $p2 ping6 -i0.01 -c3 fe80::d2f0:cff:feba:a412
ip netns exec $p1 ping6 -i0.01 -c3 fd00:f00:2::2
ip netns exec $p2 ping6 -i0.01 -c3 fd00:f00:1::2
ip netns exec $p1 ping6 -i0.01 -c3 fd00:ba4:2::2
ip netns exec $p2 ping6 -i0.01 -c3 fd00:ba4:1::2
ip netns exec $p1 ping6 -i0.01 -c3 fd00:ba4:1::1
ip netns exec $p2 ping6 -i0.01 -c3 fd00:ba4:2::1
ip netns exec $p1 traceroute -N1 fd00:ba4:2::2
ip netns exec $p2 traceroute -N1 fd00:ba4:1::2
ip netns exec $p1 traceroute -N1 fd00:f00:2::2
ip netns exec $p2 traceroute -N1 fd00:f00:1::2

0 comments on commit 46b14b0

Please sign in to comment.