On Fri, Mar 20, 2026 at 6:28 AM Lorenzo Bianconi <
[email protected]> wrote:
>
> > 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]>
>
> Hi Han,
>
> Thx for fixing it. Do we need a Fixes tag?

Thanks Lorenzo, I added it in v2.

>
> Regards,
> Lorenzo
>
> 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 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
> >
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to