When multiple logical router ports on the same router share a connected prefix and BFD is enabled on each port, northd generates BFD helper routes with identical matches but different actions.
ovn-controller represents desired flows with the same OpenFlow match using a single installed flow, so only one of these routes becomes active. The selected route can also change after a full recompute. As a result, BFD traffic for one logical router port can be routed through another port and redirected to a different gateway chassis. BFD packets generated by pinctrl already carry the BFD logical router port as MFF_LOG_INPORT. Include that logical inport in the BFD helper route match so that each BFD session selects the route associated with its own logical router port. Avoid adding the inport twice for IPv6 link-local connected routes, which are already scoped to their logical router port. Add a regression test with two logical router ports in the same IPv4 subnet and ECMP+BFD routes to the same nexthop. Reported-at: https://github.com/ovn-org/ovn/issues/330 Submitted-at: https://github.com/ovn-org/ovn/pull/331 Signed-off-by: Michal Arbet <[email protected]> --- northd/northd.c | 7 +++++++ tests/ovn-northd.at | 42 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/northd/northd.c b/northd/northd.c index 4eb2ea44b..0ad7969ca 100644 --- a/northd/northd.c +++ b/northd/northd.c @@ -13422,6 +13422,13 @@ add_route(struct lflow_table *lflows, const struct ovn_datapath *od, ds_cstr(&match), ds_cstr(&actions), lflow_ref, WITH_HINT(stage_hint)); if (op && bfd_is_port_running(bfd_ports, op->key)) { + /* BFD packets generated by ovn-controller are injected with their + * logical router port set as the logical inport. Scope this helper + * route to that port so LRPs sharing a connected prefix do not + * generate conflicting flows with identical matches. */ + if (!op_inport) { + ds_put_format(&match, " && inport == %s", op->json_key); + } ds_put_format(&match, " && udp.dst == 3784"); ovn_lflow_add(lflows, op->od, S_ROUTER_IN_IP_ROUTING, priority + 1, ds_cstr(&match), ds_cstr(&common_actions), lflow_ref, diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at index 6572b1318..8f8aa8c54 100644 --- a/tests/ovn-northd.at +++ b/tests/ovn-northd.at @@ -4653,6 +4653,47 @@ OVN_CLEANUP_NORTHD AT_CLEANUP ]) +OVN_FOR_EACH_NORTHD_NO_HV([ +AT_SETUP([BFD routes on LRPs sharing a connected subnet]) +AT_KEYWORDS([northd-bfd]) +ovn_start + +check ovn-nbctl lr-add r0 +check ovn-nbctl lrp-add r0 r0-ext-a 00:00:00:00:00:01 10.0.0.10/24 +check ovn-nbctl lrp-add r0 r0-ext-b 00:00:00:00:00:02 10.0.0.20/24 +check ovn-nbctl ls-add ext +check ovn-nbctl lsp-add-router-port ext ext-r0-a r0-ext-a +check ovn-nbctl lsp-add-router-port ext ext-r0-b r0-ext-b + +# Neutron creates these routes and BFD records directly in the NB database. +# Use the same approach here because lr-route-add rejects ECMP routes with a +# duplicate nexthop, even when they use different output ports. +check_uuid ovn-nbctl --wait=sb \ + --id=@bfd_a create bfd logical_port=r0-ext-a dst_ip=10.0.0.1 -- \ + --id=@route_a create logical_router_static_route ip_prefix=0.0.0.0/0 \ + nexthop=10.0.0.1 output_port=r0-ext-a bfd=@bfd_a -- \ + add logical_router r0 static_routes @route_a -- \ + --id=@bfd_b create bfd logical_port=r0-ext-b dst_ip=10.0.0.1 -- \ + --id=@route_b create logical_router_static_route ip_prefix=0.0.0.0/0 \ + nexthop=10.0.0.1 output_port=r0-ext-b bfd=@bfd_b -- \ + add logical_router r0 static_routes @route_b + +AT_CHECK([ovn-sbctl lflow-list | grep 'lr_in_ip_routing' | \ + grep '10.0.0.0/24' | grep 'udp.dst == 3784' | wc -l], [0], [2 +]) +AT_CHECK([ovn-sbctl lflow-list | grep 'lr_in_ip_routing' | \ + grep '10.0.0.0/24' | grep 'udp.dst == 3784' | \ + grep -c 'inport == "r0-ext-a"'], [0], [1 +]) +AT_CHECK([ovn-sbctl lflow-list | grep 'lr_in_ip_routing' | \ + grep '10.0.0.0/24' | grep 'udp.dst == 3784' | \ + grep -c 'inport == "r0-ext-b"'], [0], [1 +]) + +OVN_CLEANUP_NORTHD +AT_CLEANUP +]) + OVN_FOR_EACH_NORTHD_NO_HV([ AT_SETUP([ovn -- check CoPP config]) AT_KEYWORDS([northd-CoPP]) @@ -24351,4 +24392,3 @@ CHECK_NO_CHANGE_AFTER_RECOMPUTE OVN_CLEANUP_NORTHD AT_CLEANUP ]) - -- 2.53.0 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
