Skip to content

Commit 0ab2ae9

Browse files
frr: add basic multipath support
Using the new nexthop type group, allow multiple nexthop as a gateway from frr. The following zebra conf: ! ip route 192.168.1.20/32 cv0 ip route 192.168.1.20/32 192.168.210.3 ip route 192.168.1.20/32 192.168.210.254 ! translates into these rib nexthops: ID: 35 (zebra) RefCnt: 2 Uptime: 00:00:07 VRF: default(No AFI) Nexthop Count: 3 Valid, Installed Depends: (20) (24) (30) is directly connected, cv0 (vrf default), weight 1 via 192.168.210.3, cv0 (vrf default), weight 1 via 192.168.210.254, cv0 (vrf default), weight 1 With grout displays the proper NHs: grout# nexthop type group VRF ID ORIGIN IFACE TYPE INFO 0 35 user group id(20/1) id(24/1) id(30/1) Signed-off-by: Christophe Fontaine <[email protected]>
1 parent 6c525a9 commit 0ab2ae9

File tree

3 files changed

+103
-8
lines changed

3 files changed

+103
-8
lines changed

frr/rt_grout.c

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,12 @@ static int grout_gr_nexthop_to_frr_nexthop(
289289
nexthop_add_srv6_seg6(nh, (void *)sr6->seglist, sr6->n_seglist, encap_behavior);
290290
break;
291291
}
292+
case GR_NH_T_GROUP:
293+
nh->ifindex = gr_nh->iface_id;
294+
nh->vrf_id = gr_nh->vrf_id;
295+
*nh_family = AF_UNSPEC;
296+
nh->weight = 1;
297+
break;
292298
default:
293299
gr_log_err(
294300
"sync %s nexthops from grout not supported", gr_nh_type_name(gr_nh->type)
@@ -572,12 +578,44 @@ enum zebra_dplane_result grout_add_del_route(struct zebra_dplane_ctx *ctx) {
572578
return ZEBRA_DPLANE_REQUEST_SUCCESS;
573579
}
574580

581+
static enum zebra_dplane_result grout_add_nexthop_group(struct zebra_dplane_ctx *ctx) {
582+
enum zebra_dplane_result ret = ZEBRA_DPLANE_REQUEST_SUCCESS;
583+
uint32_t nh_id = dplane_ctx_get_nhe_id(ctx);
584+
struct gr_nexthop_info_group *group;
585+
struct gr_nh_add_req *req = NULL;
586+
size_t len;
587+
588+
len = sizeof(*req) + sizeof(*group)
589+
+ dplane_ctx_get_nhe_nh_grp_count(ctx) * sizeof(group->members[0]);
590+
if ((req = calloc(1, len)) == NULL)
591+
return ZEBRA_DPLANE_REQUEST_FAILURE;
592+
593+
group = (struct gr_nexthop_info_group *)req->nh.info;
594+
group->n_members = dplane_ctx_get_nhe_nh_grp_count(ctx);
595+
596+
req->exist_ok = true;
597+
req->nh.nh_id = nh_id;
598+
req->nh.type = GR_NH_T_GROUP;
599+
req->nh.origin = zebra2origin(dplane_ctx_get_nhe_type(ctx));
600+
601+
const struct nh_grp *nhs = dplane_ctx_get_nhe_nh_grp(ctx);
602+
for (size_t i = 0; i < group->n_members; i++) {
603+
group->members[i].nh_id = nhs[i].id;
604+
group->members[i].weight = nhs[i].weight;
605+
}
606+
607+
if (grout_client_send_recv(GR_NH_ADD, len, req, NULL) < 0)
608+
ret = ZEBRA_DPLANE_REQUEST_FAILURE;
609+
610+
free(req);
611+
return ret;
612+
}
613+
575614
static enum zebra_dplane_result grout_del_nexthop(uint32_t nh_id) {
576615
struct gr_nh_del_req req = {.missing_ok = true, .nh_id = nh_id};
577616

578617
if (grout_client_send_recv(GR_NH_DEL, sizeof(req), &req, NULL) < 0)
579618
return ZEBRA_DPLANE_REQUEST_FAILURE;
580-
581619
return ZEBRA_DPLANE_REQUEST_SUCCESS;
582620
}
583621

@@ -762,15 +800,12 @@ enum zebra_dplane_result grout_add_del_nexthop(struct zebra_dplane_ctx *ctx) {
762800
return ZEBRA_DPLANE_REQUEST_FAILURE;
763801
}
764802

765-
if (dplane_ctx_get_nhe_nh_grp_count(ctx)) {
766-
// next group are not supported in grout
767-
gr_log_err("impossible to add/del nexthop grout %u (nhg not supported)", nh_id);
768-
return ZEBRA_DPLANE_REQUEST_FAILURE;
769-
}
770-
771803
if (dplane_ctx_get_op(ctx) == DPLANE_OP_NH_DELETE)
772804
return grout_del_nexthop(nh_id);
773805

806+
if (dplane_ctx_get_nhe_nh_grp_count(ctx))
807+
return grout_add_nexthop_group(ctx);
808+
774809
return grout_add_nexthop(nh_id, origin, dplane_ctx_get_nhe_ng(ctx)->nexthop);
775810
}
776811

smoke/ip_loadbalance_frr_test.sh

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: BSD-3-Clause
3+
# Copyright (c) 2025 Christophe Fontaine
4+
5+
#
6+
# | p1 (.1.2)
7+
# [p0 ns0] --- grout --- | ns1 lo
8+
# | p2 (.2.2)
9+
#
10+
#
11+
#
12+
. $(dirname $0)/_init_frr.sh
13+
14+
p0=${run_id}0
15+
p1=${run_id}1
16+
p2=${run_id}2
17+
18+
create_interface $p0 f0:0d:ac:dc:00:00
19+
create_interface $p1 f0:0d:ac:dc:00:01
20+
create_interface $p2 f0:0d:ac:dc:00:02
21+
22+
netns_add n-$p0
23+
ip l set $p0 netns n-$p0
24+
ip -n n-$p0 link set $p0 address ba:d0:ca:ca:00:00
25+
ip -n n-$p0 link set $p0 up
26+
ip -n n-$p0 link set lo up
27+
ip -n n-$p0 addr add 172.16.0.2/24 dev $p0
28+
ip -n n-$p0 route add default via 172.16.0.1
29+
30+
netns_add n-$p1
31+
ip l set $p1 netns n-$p1
32+
ip l set $p2 netns n-$p1
33+
ip -n n-$p1 link set lo up
34+
ip -n n-$p1 addr add 192.0.0.2/32 dev lo
35+
ip -n n-$p1 link set $p1 address ba:d0:ca:ca:00:01
36+
ip -n n-$p1 link set $p1 up
37+
ip -n n-$p1 addr add 172.16.1.2/24 dev $p1
38+
ip -n n-$p1 link set $p2 address ba:d0:ca:ca:00:02
39+
ip -n n-$p1 link set $p2 up
40+
ip -n n-$p1 addr add 172.16.2.2/24 dev $p2
41+
42+
set_ip_address $p0 172.16.0.1/24
43+
set_ip_address $p1 172.16.1.1/24
44+
set_ip_address $p2 172.16.2.1/24
45+
46+
set_ip_route 192.0.0.0/24 172.16.1.2
47+
# Can't use set_ip_route a second time
48+
# as the helper will look for the route
49+
# --> Configure it manually
50+
vtysh <<-EOF
51+
configure terminal
52+
ip route 192.0.0.0/24 172.16.2.2
53+
EOF
54+
55+
ip -n n-$p1 route add default via 172.16.1.1
56+
ip netns exec n-$p0 ping 192.0.0.2 -i0.01 -c 3
57+
58+
ip -n n-$p1 route del default
59+
ip -n n-$p1 route add default via 172.16.2.1
60+
ip netns exec n-$p0 ping 192.0.0.2 -i0.01 -c 3

subprojects/packagefiles/frr/meson-add-dependency-definition.patch

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ index 0000000..d26e979
103103
+ '"' + srcdir + '/configure" ' +
104104
+ '--prefix="' + prefix + '" ' +
105105
+ '--with-moduledir="' + moduledir + '" ' +
106-
+ '--disable-doc --enable-multipath=1 ' +
106+
+ '--disable-doc --enable-multipath=128 ' +
107107
+ '--disable-ripd --disable-ripngd --disable-ospfd --disable-ospf6d ' +
108108
+ '--disable-ldpd --disable-nhrpd --disable-eigrpd --disable-babeld ' +
109109
+ '--disable-isisd --disable-pimd --disable-pim6d --disable-pbrd --disable-fabricd ' +

0 commit comments

Comments
 (0)