When resolving the output port and LRP address for a static route, use
the nexthop's address family (not the prefix) for the is_ipv4 parameter
to find_static_route_outport. This matters when the "first IP on port"
fallback is used (nexthop not in any LRP network): we must pick the
first IPv4 or IPv6 address according to the nexthop family, so that
ARP/ND can work. In add_route() the register type (reg5 for IPv4 vs
xxreg1 for IPv6) is determined by the nexthop's address family, which is
correct. Without this fix it can end up with assigning an IPv6 address
to the 32-bit reg5.
Fixes: 559924291c7f ("northd: Handle routing for other address families.")
Assisted-by: Cursor, with model: claude-4.6-opus-high
Signed-off-by: Han Zhou <[email protected]>
Acked-by: Lorenzo Bianconi <[email protected]>
---
northd/northd.c | 3 ++-
tests/ovn-northd.at | 5 +++++
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/northd/northd.c b/northd/northd.c
index 70cd6a644a84..4b87c2305c20 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -12266,7 +12266,8 @@ parsed_routes_add_static(const struct ovn_datapath *od,
struct ovn_port *out_port = NULL;
if (!is_discard_route &&
!find_static_route_outport(od, lr_ports, route,
- IN6_IS_ADDR_V4MAPPED(&prefix),
+ nexthop ? IN6_IS_ADDR_V4MAPPED(nexthop)
+ : IN6_IS_ADDR_V4MAPPED(&prefix),
&lrp_addr_s, &out_port)) {
free(nexthop);
return;
diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at
index 1afdbbf2ea9d..587ce94148e4 100644
--- a/tests/ovn-northd.at
+++ b/tests/ovn-northd.at
@@ -7395,6 +7395,10 @@ check ovn-nbctl --wait=sb lr-route-add lr0 11.0.0.0/24
2001:db8::10
check ovn-nbctl --wait=sb lr-route-add lr0 2001:db8:1::/64 192.168.0.20
check ovn-nbctl --wait=sb lr-route-add lr0 2001:db8:2::/64 2001:db8::20
+# Add a IPv6 route with IPv4 nexthop that is not on any subnet of the router
port.
+# It should select the first IPv4 and assign to REG_SRC_IPV4 (reg5).
+check ovn-nbctl --wait=sb lr-route-add lr0 2001:db8:3::/64 192.168.1.10
lr0-public
+
ovn-sbctl dump-flows lr0 > lr0flows
AT_CHECK([grep -e "lr_in_ip_routing " lr0flows | ovn_strip_lflows], [0], [dnl
table=??(lr_in_ip_routing ), priority=0 , match=(1), action=(drop;)
@@ -7404,6 +7408,7 @@ AT_CHECK([grep -e "lr_in_ip_routing " lr0flows |
ovn_strip_lflows], [0], [dnl
table=??(lr_in_ip_routing ), priority=198 , match=(ip4.dst ==
192.168.0.0/24), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = ip4.dst; reg5 =
192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public";
flags.loopback = 1; reg9[[9]] = 1; next;)
table=??(lr_in_ip_routing ), priority=516 , match=(reg7 == 0 && ip6.dst
== 2001:db8:1::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.0.20;
reg5 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public";
flags.loopback = 1; reg9[[9]] = 1; next;)
table=??(lr_in_ip_routing ), priority=516 , match=(reg7 == 0 && ip6.dst
== 2001:db8:2::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 =
2001:db8::20; xxreg1 = 2001:db8::1; eth.src = 00:00:20:20:12:14; outport =
"lr0-private"; flags.loopback = 1; reg9[[9]] = 0; next;)
+ table=??(lr_in_ip_routing ), priority=516 , match=(reg7 == 0 && ip6.dst
== 2001:db8:3::/64), action=(ip.ttl--; reg8[[0..15]] = 0; reg0 = 192.168.1.10;
reg5 = 192.168.0.1; eth.src = 00:00:20:20:12:13; outport = "lr0-public";
flags.loopback = 1; reg9[[9]] = 1; next;)
table=??(lr_in_ip_routing ), priority=518 , match=(inport ==
"lr0-private" && ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0;
xxreg0 = ip6.dst; xxreg1 = fe80::200:20ff:fe20:1214; eth.src =
00:00:20:20:12:14; outport = "lr0-private"; flags.loopback = 1; reg9[[9]] = 0;
next;)
table=??(lr_in_ip_routing ), priority=518 , match=(inport == "lr0-public"
&& ip6.dst == fe80::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 =
ip6.dst; xxreg1 = fe80::200:20ff:fe20:1213; eth.src = 00:00:20:20:12:13;
outport = "lr0-public"; flags.loopback = 1; reg9[[9]] = 0; next;)
table=??(lr_in_ip_routing ), priority=518 , match=(ip6.dst ==
2001:db8::/64), action=(ip.ttl--; reg8[[0..15]] = 0; xxreg0 = ip6.dst; xxreg1 =
2001:db8::1; eth.src = 00:00:20:20:12:14; outport = "lr0-private";
flags.loopback = 1; reg9[[9]] = 0; next;)
--
2.38.1
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev