Skip to content

Commit f40d836

Browse files
icmp,icmp6: select nexthop based on ident field
icmp(6)_local_send access the nexthop to select the proper gateway. This can't work with the nexthop group. As we can't use the rss field, use the "ident" field instead. Add smoke test for loadbalance. Signed-off-by: Christophe Fontaine <[email protected]>
1 parent 8e41100 commit f40d836

File tree

3 files changed

+82
-0
lines changed

3 files changed

+82
-0
lines changed

modules/ip/datapath/icmp_local_send.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <gr_ip4_datapath.h>
1111
#include <gr_log.h>
1212
#include <gr_mbuf.h>
13+
#include <gr_vec.h>
1314

1415
#include <rte_icmp.h>
1516
#include <rte_ip.h>
@@ -46,6 +47,13 @@ int icmp_local_send(
4647
struct ctl_to_stack *msg;
4748
int ret;
4849

50+
if (gw->type == GR_NH_T_GROUP) {
51+
struct nexthop_info_group *g = (struct nexthop_info_group *)gw->info;
52+
if (g->n_members == 0)
53+
return errno_set(EHOSTUNREACH);
54+
gw = g->members[ident % g->n_members].nh;
55+
}
56+
4957
if ((msg = calloc(1, sizeof(struct ctl_to_stack))) == NULL)
5058
return errno_set(ENOMEM);
5159

@@ -105,6 +113,11 @@ static uint16_t icmp_local_send_process(
105113
icmp->icmp_seq_nb = rte_cpu_to_be_16(msg->seq_num);
106114
icmp->icmp_ident = rte_cpu_to_be_16(msg->ident);
107115

116+
// Fake RSS to spread the traffic
117+
// for ECMP routes or active/active bonds.
118+
mbuf->hash.rss = msg->ident;
119+
mbuf->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
120+
108121
data = ip_local_mbuf_data(mbuf);
109122
data->proto = IPPROTO_ICMP;
110123
data->len = sizeof(*icmp) + sizeof(clock_t);

modules/ip6/datapath/icmp6_local_send.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <gr_ip6_datapath.h>
1212
#include <gr_log.h>
1313
#include <gr_mbuf.h>
14+
#include <gr_vec.h>
1415

1516
#include <rte_ip6.h>
1617

@@ -46,6 +47,13 @@ int icmp6_local_send(
4647
const struct nexthop *local;
4748
int ret;
4849

50+
if (gw->type == GR_NH_T_GROUP) {
51+
struct nexthop_info_group *g = (struct nexthop_info_group *)gw->info;
52+
if (g->n_members == 0)
53+
return errno_set(EHOSTUNREACH);
54+
gw = g->members[ident % g->n_members].nh;
55+
}
56+
4957
if ((local = addr6_get_preferred(gw->iface_id, &nexthop_info_l3(gw)->ipv6)) == NULL)
5058
return -errno;
5159

@@ -94,6 +102,11 @@ static uint16_t icmp6_local_send_process(
94102
icmp6_echo->ident = rte_cpu_to_be_16(msg->ident);
95103
icmp6_echo->seqnum = rte_cpu_to_be_16(msg->seq_num);
96104

105+
// Fake RSS to spread the traffic
106+
// for ECMP routes or active/active bonds.
107+
mbuf->hash.rss = msg->ident;
108+
mbuf->ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
109+
97110
payload = PAYLOAD(icmp6_echo);
98111
*payload = gr_clock_us();
99112

smoke/ip_loadbalance_test.sh

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/bin/bash
2+
# SPDX-License-Identifier: BSD-3-Clause
3+
# Copyright (c) 2025 Christophe Fontaine
4+
5+
. $(dirname $0)/_init.sh
6+
7+
p0=${run_id}0
8+
p1=${run_id}1
9+
p2=${run_id}2
10+
11+
grcli interface add port $p0 devargs net_tap0,iface=$p0 mac f0:0d:ac:dc:00:00
12+
grcli interface add port $p1 devargs net_tap1,iface=$p1 mac f0:0d:ac:dc:00:01
13+
grcli interface add port $p2 devargs net_tap2,iface=$p2 mac f0:0d:ac:dc:00:02
14+
15+
grcli address add 172.16.0.1/24 iface $p0
16+
grcli address add 172.16.1.1/24 iface $p1
17+
grcli address add 172.16.2.1/24 iface $p2
18+
19+
netns_add ${run_id}
20+
ip -n ${run_id} link set lo up
21+
ip -n ${run_id} addr add 192.200.0.2/24 dev lo
22+
23+
for n in 0 1; do
24+
p=$run_id$n
25+
ip link set $p netns ${run_id}
26+
ip -n ${run_id} link set $p address ba:d0:ca:ca:00:0$n
27+
ip -n ${run_id} link set $p up
28+
ip -n ${run_id} addr add 172.16.$n.2/24 dev $p
29+
done
30+
31+
# Add ECMP route
32+
grcli nexthop add l3 iface $p0 address 172.16.0.2 id 100
33+
grcli nexthop add l3 iface $p1 address 172.16.1.2 id 101
34+
grcli nexthop add group id 10 members nh 100 nh 101
35+
grcli route add 192.200.0.0/24 via id 10
36+
37+
# Locally generated ICMP requests
38+
grcli ping 192.200.0.2 count 1 ident 1
39+
grcli ping 192.200.0.2 count 1 ident 2
40+
41+
# Externally generated ICMP requests
42+
ip -n ${run_id} nexthop add id 1601 via 172.16.0.1 dev $p0
43+
ip -n ${run_id} nexthop add id 1611 via 172.16.1.1 dev $p1
44+
ip -n ${run_id} nexthop add id 1620 group 1601/1611
45+
46+
ip -n ${run_id} route add 172.16.2.0/24 nhid 1620
47+
48+
netns_add $p2
49+
ip link set $p2 netns $p2
50+
ip -n $p2 link set $p2 address ba:d0:ca:ca:00:02
51+
ip -n $p2 link set $p2 up
52+
ip -n $p2 addr add 172.16.2.2/24 dev $p2
53+
ip -n $p2 route add default via 172.16.2.1
54+
ip netns exec $p2 ping 192.200.0.2 -c 3
55+
56+
grcli nexthop del 10

0 commit comments

Comments
 (0)