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.
Assisted-by: Cursor, with model: claude-4.6-opus-high Signed-off-by: Han Zhou <[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 31e42f7a1a97..297892a1630e 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -12263,7 +12263,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 f03708867717..0fb59f68ffc3 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
