On 5/18/26 5:47 AM, jay wrote: > Hi Numan, > Hi JayGue Lee, Numan,
> Thanks for the detailed feedback. You are right — v5 does not handle > the case where ovn-controller stamps the probe with $svc_monitor_mac > and routes it through the LRP (i.e. inport at ls_in_l2_lkup is the > localnet port, not the backend LSP). I missed that scenario. > > I have implemented the alternative approach you suggested (rewriting > inport at S_SWITCH_IN_CHECK_PORT_SEC) and sent it as v6: > > > https://patchwork.ozlabs.org/project/ovn/patch/[email protected]/ > > For each external LSP on a localnet switch, v6 installs: > > table=ls_in_check_port_sec, priority=75, > match=(inport == <localnet> && eth.src == <ext_lsp_mac>), > action=(flags.localnet = 1; inport = <ext_lsp>; next;) > > This makes the original per-backend HM reply lflow at ls_in_l2_lkup > work without modification, which is the elegant part. > > However, the early inport rewrite has side-effects on downstream > stages that previously relied on inport being the localnet port for > external LSP traffic. To keep existing functionality intact, v6 also > needed: > > 1. DHCP (ls_in_dhcp_options / ls_in_dhcp_response): > The external-LSP path no longer iterates localnet_ports to set > inport; it now passes the external LSP directly (since inport > already *is* the external LSP after the rewrite). > > 2. ARP/ND drop flows (build_drop_arp_nd_flows_for_unbound_router_ports): > Match clauses changed from inport == <localnet> to > inport == <ext_lsp> for the same reason. > > 3. flags.localnet preservation: > The rewrite action explicitly sets flags.localnet = 1 because the > existing S_SWITCH_IN_LOOKUP_FDB lflow that normally sets this flag > matches on inport == <localnet>, which no longer fires after the > rewrite. > > CI result: the only failure is the known-flaky > "system-test-userspace 201- unstable" job, which has been failing on > unrelated patches throughout 2026 (e.g. 597e4ac, 18d7827). All other > 25 jobs pass. > > Both v5 and v6 fix the original bug. The trade-off: > > - v5: self-contained change at ls_in_l2_lkup only; uses > flags.localnet + outport trick; does not touch other stages. > - v6: structurally cleaner (single inport rewrite benefits all > downstream lflows); but the blast radius is larger — changes touch > DHCP, ARP/ND, and FDB logic. > > I am happy to go with whichever approach you and the other maintainers > prefer. Let me know what you think. > I'll try to have a look at v6 in the near future - at a quick glance over the discussion above it kind of makes sense to me; I guess it's OK to move future discussions on that version of the patch. Regards, Dumitru > Thanks > JayGue Lee > > On Sat, May 16, 2026 at 7:46 AM Numan Siddique <[email protected]> wrote: > >> On Mon, May 11, 2026 at 11:40 PM JayGue Lee <[email protected]> wrote: >>> >>> >>> build_lb_health_check_response_lflows() builds a per-backend >>> service_monitor reply punt lflow with the match: >>> >>> inport == "<backend_lsp>" && ip4.dst == <svc_mon_src_ip> && >>> ip4.src == <backend_ip> && eth.dst == <svc_mon_lrp_mac> && >>> tcp.src == <backend_port> >>> >>> When the backend's LSP is type=external on a Logical_Switch that has >>> a localnet port (the typical configuration produced by Neutron / >>> ovn-octavia-provider for baremetal pool members on a provider VLAN), >>> the probe reply re-enters br-int through the localnet port. At the >>> time the lflow is evaluated MFF_LOG_INPORT therefore carries the >>> localnet LSP's tunnel_key, not the backend LSP's, and >>> 'inport == "<backend_lsp>"' never matches. >>> >>> Even if the match is rewritten to 'inport == "<localnet_lsp>"', >>> 'handle_svc_check(inport);' alone is not sufficient: pinctrl indexes >>> its svc_monitors_map by (dp_key, port_key) where port_key equals the >>> backend LSP's tunnel_key (sync_svc_monitors() in controller/pinctrl.c >>> sets svc_mon->port_key = pb->tunnel_key from >>> sb_svc_mon->logical_port). pinctrl_find_svc_monitor() therefore >>> requires MFF_LOG_INPORT to hold the backend LSP's tunnel_key when >>> the controller op fires, otherwise the lookup fails silently and >>> Service_Monitor.status stays 'offline' indefinitely even though the >>> backend is fully reachable on the wire. >>> >>> Detect type=external backends on a Logical_Switch with a localnet >>> port and substitute a localnet-aware reply lflow: >>> >>> match : flags.localnet == 1 && eth.src == <bm_mac> && >>> ip{4,6}.dst == <svc_mon_src_ip> && >>> ip{4,6}.src == <backend_ip> && >>> eth.dst == <svc_mon_lrp_mac> && <proto-tail> >>> action : outport = "<backend_lsp>"; >>> handle_svc_check(outport); >>> outport = ""; >>> >>> flags.localnet is set in S_SWITCH_IN_LOOKUP_FDB on packets arriving >>> from any localnet port (commit e6ffc4919c388, "northd: Enable ARP/ND >>> responder for localnet-sourced requests."), so it identifies the >>> re-entry path independently of which localnet LSP the packet came >>> through (a switch may have several). eth.src disambiguates which >>> baremetal backend on that localnet. >>> >>> handle_svc_check(<field>) saves MFF_LOG_INPORT, moves <field> into >>> it, runs the controller op, and restores MFF_LOG_INPORT >>> (encode_HANDLE_SVC_CHECK() in lib/actions.c). Borrowing >>> MFF_LOG_OUTPORT to carry the backend LSP's tunnel_key into >>> MFF_LOG_INPORT for the punt is exactly what pinctrl needs and is the >>> same semantics as the manual workaround flow operators install today >>> ('actions=set_field:<bm_tunnel_key>->reg14, controller(...)'). >>> 'outport = "";' clears MFF_LOG_OUTPORT afterwards so the cleared >>> value does not leak into egress and reflect the reply back to the >>> backend. >>> >>> Regular (non-external) backends are unchanged. >>> >>> Suggested-by: Numan Siddique <[email protected]> >>> Signed-off-by: JayGue Lee <[email protected]> >> >> Thanks for the patch. >> >> Looks to me your solution is incomplete. >> >> With LB health checks, CMS/user can configure to use a private IP >> from the subnet >> or the router port IP as the source IP for the health checks generated >> by ovn-controller. >> >> The code you've added only handles the scenario when the router port >> IP is configured >> to use as the source ip. The test case you added confirms that. >> >> It is also possible that the user can configure some other private IP >> from the same subnet in which case >> ovn-controller will use the $svc_monitor_mac (which is generated and >> stored in nb_global) >> as the source mac when it sends out the health check packet. For this >> scenario the existing logical flow >> (which is shown below) will be matched and ovn-controller ignore it as >> the inport is localnet port and not external port. >> >> There is one more inline comment below. Please see. >> >> >> Instead of the approach you have taken in this patch which is to add >> logical flows which checks on >> "flags.localnet == 1" how about we do the following ? >> >> - In the logical switch pipeline just after port security checks >> we can add another stage (or in the apply port security stage itself) >> which matches on localnet port and eth.src == <external_port_mac> >> and rewrites the inport to the actual external port. >> >> Eg. >> if there is an external port "foo_external_port" with mac >> "00:00:01:00:00:50" then add the flow like below >> >> table=0 (ls_in_check_port_sec), priority=70 , match=(inport == >> "localnet-port" && eth.src == 00:00:01:00:00:50), action=(inport = >> "foo_external_port"; next;) >> >> I think if we do this, then we don't have to match on localnet port >> and eth.src down the line in other pipeline stages of the logical >> switch. >> And the existing logical flows for the handle_svc_check() would work >> without any issues. >> >> The downside of this approach is that it will break DHCP for external >> ports (and maybe a few others). I think those can be fixed. >> >> I am not forcing this approach, but checking if it makes sense to do >> this way. If not we can continue with your patch and address the >> comments which I provided above. >> >> @Dumitru Ceara @Ales Musil @Mark Michelson @Han Zhou and others, do >> you have any thoughts on this ? >> >> @JayGue Lee Either you can wait for comments from others or address >> the review comments and submit v6 meanwhile. >> >> >> Thanks >> Numan >> >>> --- >>> v5 (this revision): >>> - Test-only fix. In v3/v4 the new ovn-northd.at unit test >>> used 'check ovn-nbctl ... -- --id=@hc create >>> Load_Balancer_Health_Check ...' which caused the testsuite >>> to fail because the create command prints the new row's >>> UUID to stdout while 'check' expects an empty stdout (see >>> Documentation/topics/test-development.rst). Replaced with >>> 'check_uuid', matching the convention used elsewhere in >>> the same file (e.g. tests/ovn-northd.at:1506). No >>> functional change. Verified locally on a Linux VM: >>> 227/227 ovn-northd.at unit tests PASS, including the new >>> 687/688 (parallelization=yes/no). >>> v4: >>> - Address 0-day Robot checkpatch warnings on v3: two >>> ds_put_format() lines in build_lb_health_check_response_lflows() >>> were 80 chars after the new 'else' indentation pushed them over >>> the 79-char limit. Fixed by breaking the format string onto a >>> new line, matching the style already used in the new >>> 'external_via_localnet' branch. No functional change. >>> v3: >>> - Address review feedback from Numan Siddique on the original >>> bug report thread (ovs-discuss). Numan suggested fixing the >>> existing reply lflow rather than adding a new one, by matching >>> on inport == <localnet_port> when the backend is type=external. >>> - Restructure the patch accordingly: instead of emitting a second >>> lflow at the same priority, the existing per-backend reply lflow >>> is now a single ovn_lflow_add() whose match/action are branched >>> when the backend is type=external on a Logical_Switch with a >>> localnet port. This is a smaller and conceptually cleaner change >>> than v2 (no duplicate lflows on the same datapath, no priority >>> overlap to reason about). >>> - Match uses 'flags.localnet == 1 && eth.src == <bm_mac>' instead >>> of 'inport == "<localnet_lsp>"'. flags.localnet is now set in >>> S_SWITCH_IN_LOOKUP_FDB by commit e6ffc4919c388 ("northd: Enable >>> ARP/ND responder for localnet-sourced requests."), so a single >>> predicate covers Logical_Switches that have multiple localnet >>> LSPs (which is common in Neutron provider deployments). eth.src >>> disambiguates which baremetal backend on that localnet. >>> - Action piece preserved from v2 ('outport = "<backend_lsp>"; >>> handle_svc_check(outport); outport = "";'). Match-only fixes do >>> not work because pinctrl_find_svc_monitor() (controller/pinctrl.c) >>> indexes svc_monitors_map by (dp_key, port_key) where port_key is >>> the backend LSP's tunnel_key, so MFF_LOG_INPORT must hold that >>> tunnel_key when the controller op fires. This is also what the >>> manual workaround flow operators install today >>> ('actions=set_field:<bm_tunnel_key>->reg14, controller(...)') does >>> in production, confirmed against a live br-int dump. >>> - Use ls_has_localnet_port() helper added by commit 9699f8922c02747 >>> ("northd: Add ls_has_localnet_port() helper.") instead of the >>> open-coded vector_is_empty(&od->localnet_ports) check. >>> - Updated commit subject to "Fix HM reply lflow for type=external >>> backends on localnet LS." to reflect that v3 modifies the >>> existing lflow rather than generating a new one. >>> - Test rewritten: a single Logical_Router peers with two switches >>> (a regular tenant LS with a VM backend, and a provider LS with a >>> localnet port and a type=external backend) and a single LB binds >>> both backends. The test asserts the regular backend keeps the >>> original 'inport == "<vm-port>" / handle_svc_check(inport);' >>> behavior and the type=external backend gets the localnet-aware >>> match and the outport-borrowing action. >>> v2: >>> - Replaced the ovn_port_find() call (which crashed on >>> peer_switch_od->ports because that hmap is keyed on dp_node, not >>> key_node) with an inline HMAP_FOR_EACH (dp_node, ...) loop. >>> >>> NEWS | 6 +++ >>> northd/northd.c | 96 ++++++++++++++++++++++++++++++++++++++------ >>> tests/ovn-northd.at | 98 +++++++++++++++++++++++++++++++++++++++++++++ >>> 3 files changed, 187 insertions(+), 13 deletions(-) >>> >>> diff --git a/NEWS b/NEWS >>> index 68cdbff..0fa8a07 100644 >>> --- a/NEWS >>> +++ b/NEWS >>> @@ -6,6 +6,12 @@ Post v26.03.0 >>> * Add ECMP/multi-homing support for EVPN FDB entries. FDB entries >>> backed by a kernel nexthop group are load-balanced via OpenFlow >>> select groups with weighted buckets. >>> + - Fixed Load_Balancer health check replies failing silently for >>> + baremetal pool members whose backend LSP is type=external on a >>> + Logical_Switch that has a localnet port. ovn-northd now emits a >>> + localnet-aware reply lflow (matched on flags.localnet + eth.src) >>> + and loads the backend LSP's tunnel_key into MFF_LOG_INPORT for >>> + the controller dispatch so pinctrl_find_svc_monitor() succeeds. >>> >>> OVN v26.03.0 - xxx xx xxxx >>> -------------------------- >>> diff --git a/northd/northd.c b/northd/northd.c >>> index 8305e04..cc1c2ef 100644 >>> --- a/northd/northd.c >>> +++ b/northd/northd.c >>> @@ -8922,30 +8922,82 @@ build_lb_health_check_response_lflows( >>> continue; >>> } >>> >>> + /* For backends whose LSP is type=external on a switch with >> a >>> + * localnet port (typical for Neutron / ovn-octavia-provider >>> + * baremetal pool members on a provider VLAN), the reply >>> + * re-enters br-int via the localnet port. At that point >>> + * MFF_LOG_INPORT carries the localnet LSP's tunnel_key, not >>> + * the backend's, so the original 'inport == <backend>' >> match >>> + * never fires and pinctrl_handle_svc_check() never runs. >>> + * >>> + * Detect that case here so we can substitute a >> localnet-aware >>> + * match (keyed on flags.localnet + eth.src) and an action >>> + * that loads the backend LSP's tunnel_key into >> MFF_LOG_INPORT >>> + * before dispatching to ovn-controller, which is what >>> + * pinctrl_find_svc_monitor() keys on. */ >>> + struct ovn_port *backend_op = NULL; >>> + struct ovn_port *op; >>> + HMAP_FOR_EACH (op, dp_node, &peer_switch_od->ports) { >>> + if (op->nbsp && op->key >>> + && !strcmp(op->key, backend_nb->logical_port)) { >>> + backend_op = op; >>> + break; >>> + } >>> + } >>> + bool external_via_localnet = >>> + backend_op && backend_op->nbsp && backend_op->nbsp->type >>> + && !strcmp(backend_op->nbsp->type, "external") >>> + && backend_op->n_lsp_addrs >>> + && ls_has_localnet_port(peer_switch_od); >>> + >>> ds_clear(match); >>> ds_clear(action); >>> >>> /* icmp6 type 1 and icmp4 type 3 are included in the match, >> because >>> * the controller is using them to detect unreachable >> ports. */ >>> if (addr_is_ipv6(backend_nb->svc_mon_src_ip)) { >>> - ds_put_format(match, "inport == \"%s\" && ip6.dst == %s >> && " >>> - "ip6.src == %s && eth.dst == %s && ", >>> - backend_nb->logical_port, >>> - backend_nb->svc_mon_src_ip, >>> - backend->ip_str, >>> - >> backend_nb->svc_mon_lrp->lrp_networks.ea_s); >>> + if (external_via_localnet) { >>> + ds_put_format(match, >>> + "flags.localnet == 1 && eth.src == %s >> && " >>> + "ip6.dst == %s && ip6.src == %s && " >>> + "eth.dst == %s && ", >>> + backend_op->lsp_addrs[0].ea_s, >>> + backend_nb->svc_mon_src_ip, >>> + backend->ip_str, >>> + >> backend_nb->svc_mon_lrp->lrp_networks.ea_s); >>> + } else { >>> + ds_put_format(match, >>> + "inport == \"%s\" && ip6.dst == %s && >> " >>> + "ip6.src == %s && eth.dst == %s && ", >>> + backend_nb->logical_port, >>> + backend_nb->svc_mon_src_ip, >>> + backend->ip_str, >>> + >> backend_nb->svc_mon_lrp->lrp_networks.ea_s); >>> + } >>> if (!strcmp(protocol, "tcp")) { >>> ds_put_format(match, "tcp.src == %s", >> backend->port_str); >>> } else { >>> ds_put_cstr(match, "icmp6.type == 1"); >>> } >>> } else { >>> - ds_put_format(match, "inport == \"%s\" && ip4.dst == %s >> && " >>> - "ip4.src == %s && eth.dst == %s && ", >>> - backend_nb->logical_port, >>> - backend_nb->svc_mon_src_ip, >>> - backend->ip_str, >>> - >> backend_nb->svc_mon_lrp->lrp_networks.ea_s); >>> + if (external_via_localnet) { >>> + ds_put_format(match, >>> + "flags.localnet == 1 && eth.src == %s >> && " >>> + "ip4.dst == %s && ip4.src == %s && " >>> + "eth.dst == %s && ", >>> + backend_op->lsp_addrs[0].ea_s, >>> + backend_nb->svc_mon_src_ip, >>> + backend->ip_str, >>> + >> backend_nb->svc_mon_lrp->lrp_networks.ea_s); >>> + } else { >>> + ds_put_format(match, >>> + "inport == \"%s\" && ip4.dst == %s && >> " >>> + "ip4.src == %s && eth.dst == %s && ", >>> + backend_nb->logical_port, >>> + backend_nb->svc_mon_src_ip, >>> + backend->ip_str, >>> + >> backend_nb->svc_mon_lrp->lrp_networks.ea_s); >>> + } >>> if (!strcmp(protocol, "tcp")) { >>> ds_put_format(match, "tcp.src == %s", >> backend->port_str); >>> } else { >>> @@ -8953,6 +9005,24 @@ build_lb_health_check_response_lflows( >>> } >>> } >>> >>> + /* For the type=external/localnet case, MFF_LOG_INPORT at >> this >>> + * point holds the localnet LSP's tunnel_key but pinctrl >> indexes >>> + * Service_Monitor by the backend LSP's tunnel_key. Borrow >>> + * MFF_LOG_OUTPORT to carry the backend LSP's tunnel_key >> into >>> + * MFF_LOG_INPORT for the controller dispatch >> (handle_svc_check() >>> + * saves/moves/restores MFF_LOG_INPORT around the punt), >> then >>> + * clear outport so the cleared MFF_LOG_OUTPORT does not >> leak >>> + * into egress. */ >>> + if (external_via_localnet) { >>> + ds_put_format(action, >>> + "outport = \"%s\"; " >>> + "handle_svc_check(outport); " >>> + "outport = \"\";", >>> + backend_nb->logical_port); >> >> Why do you set outport to the backend logical port name ? >> ovn-controller expects the inport to be set right ? >> The action should set inport right ? >> >> i.e >> uint32_t port_key = md->flow.regs[MFF_LOG_INPORT - MFF_REG0]; >> >> >> Thanks >> Numan >> >>> + } else { >>> + ds_put_cstr(action, "handle_svc_check(inport);"); >>> + } >>> + >>> /* ovn-controller expects health check responses from the LS >>> * datapath in which the backend is located. That's why we >>> * install the response lflow into the peer's datapath. */ >>> @@ -8960,7 +9030,7 @@ build_lb_health_check_response_lflows( >>> >> peer_switch_od->nbs->copp, >>> meter_groups); >>> ovn_lflow_add(lflows, peer_switch_od, S_SWITCH_IN_L2_LKUP, >> 110, >>> - ds_cstr(match), "handle_svc_check(inport);", >>> + ds_cstr(match), ds_cstr(action), >>> lb_dps->lflow_ref, WITH_CTRL_METER(meter)); >>> } >>> } >>> diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at >>> index 074b152..708586c 100644 >>> --- a/tests/ovn-northd.at >>> +++ b/tests/ovn-northd.at >>> @@ -1687,6 +1687,104 @@ OVN_CLEANUP_NORTHD >>> AT_CLEANUP >>> ]) >>> >>> +OVN_FOR_EACH_NORTHD_NO_HV_PARALLELIZATION([ >>> +AT_SETUP([Load balancer health check reply lflow for type=external >> backend on localnet LS]) >>> +ovn_start >>> + >>> +# Topology: >>> +# >>> +# lr0 --(lr0-sw0)-- sw0 (regular tenant LS, 10.0.0.0/24) >>> +# `-- vm-port (type="", regular VIF backend) >>> +# >>> +# lr0 --(lr0-prov)-- prov (provider LS with localnet) >>> +# |-- prov-localnet (type=localnet) >>> +# `-- bm-port (type=external, baremetal pool >> member) >>> +# >>> +# A baremetal LB pool member's LSP is type=external; replies to HM >> probes >>> +# re-enter br-int via the localnet port, so MFF_LOG_INPORT carries the >>> +# localnet LSP's tunnel_key and the original >>> +# "inport == <bm-port> && ... ; handle_svc_check(inport);" >>> +# reply lflow never matches. pinctrl_find_svc_monitor() is keyed on >>> +# (dp_key, port_key) where port_key = backend LSP's tunnel_key, so >>> +# MFF_LOG_INPORT must hold that tunnel_key when the controller op fires. >>> +# >>> +# The fix replaces the per-backend reply lflow's match/action when the >>> +# backend is type=external on a switch with a localnet port: >>> +# match : "flags.localnet == 1 && eth.src == <bm_mac> && ..." >>> +# action : "outport = "<bm-port>"; handle_svc_check(outport); outport >> = "";" >>> +# handle_svc_check() saves/moves/restores MFF_LOG_INPORT around the >> punt, >>> +# so dispatch sees REG14 = bm-port's tunnel_key as required by pinctrl. >>> +# Regular (non-external) backends keep the original behavior. >>> + >>> +check ovn-nbctl lr-add lr0 >>> +check ovn-nbctl lrp-add lr0 lr0-sw0 00:00:00:00:01:01 10.0.0.1/24 >>> +check ovn-nbctl lrp-add lr0 lr0-prov 00:00:00:00:02:01 10.0.50.1/24 >>> + >>> +check ovn-nbctl ls-add sw0 >>> +check ovn-nbctl --wait=sb lsp-add sw0 sw0-lr0 \ >>> + -- lsp-set-type sw0-lr0 router \ >>> + -- lsp-set-options sw0-lr0 router-port=lr0-sw0 \ >>> + -- lsp-set-addresses sw0-lr0 router >>> +check ovn-nbctl --wait=sb lsp-add sw0 vm-port \ >>> + -- lsp-set-addresses vm-port "00:00:00:00:01:02 10.0.0.10" >>> + >>> +check ovn-nbctl ls-add prov >>> +check ovn-nbctl --wait=sb lsp-add prov prov-lr0 \ >>> + -- lsp-set-type prov-lr0 router \ >>> + -- lsp-set-options prov-lr0 router-port=lr0-prov \ >>> + -- lsp-set-addresses prov-lr0 router >>> +check ovn-nbctl --wait=sb lsp-add prov prov-localnet \ >>> + -- lsp-set-type prov-localnet localnet \ >>> + -- lsp-set-options prov-localnet network_name=physnet1 \ >>> + -- lsp-set-addresses prov-localnet unknown >>> +check ovn-nbctl --wait=sb lsp-add prov bm-port \ >>> + -- lsp-set-type bm-port external \ >>> + -- lsp-set-addresses bm-port "00:00:00:00:02:0a 10.0.50.10" >>> + >>> +check ovn-sbctl chassis-add hv1 geneve 127.0.0.1 >>> +check ovn-sbctl lsp-bind vm-port hv1 >>> +check ovn-sbctl lsp-bind bm-port hv1 >>> + >>> +# LB has both a regular-VIF backend on sw0 and a type=external backend >> on prov. >>> +check ovn-nbctl lb-add lb1 192.168.0.10:80 10.0.0.10:80,10.0.50.10:80 >> tcp >>> +check ovn-nbctl --wait=sb set load_balancer lb1 \ >>> + ip_port_mappings:10.0.0.10=vm-port:10.0.0.1 >>> +check ovn-nbctl --wait=sb set load_balancer lb1 \ >>> + ip_port_mappings:10.0.50.10=bm-port:10.0.50.1 >>> + >>> +check_uuid ovn-nbctl --wait=sb -- --id=@hc create >> Load_Balancer_Health_Check \ >>> + vip="192.168.0.10\:80" -- add Load_Balancer lb1 health_check @hc >>> + >>> +check ovn-nbctl lr-lb-add lr0 lb1 >>> +check ovn-nbctl ls-lb-add sw0 lb1 >>> +check ovn-nbctl ls-lb-add prov lb1 >>> +check ovn-nbctl --wait=sb sync >>> + >>> +# Regular backend on sw0: original "inport == <vm-port>" / >> "handle_svc_check(inport);" >>> +# behavior unchanged. >>> +AT_CAPTURE_FILE([sw0_lflows]) >>> +ovn-sbctl dump-flows sw0 | grep ls_in_l2_lkup | grep handle_svc_check \ >>> + > sw0_lflows >>> +AT_CHECK([cat sw0_lflows | ovn_strip_lflows], [0], [dnl >>> + table=??(ls_in_l2_lkup ), priority=110 , match=(eth.dst == >> $svc_monitor_mac && (tcp || icmp || icmp6)), >> action=(handle_svc_check(inport);) >>> + table=??(ls_in_l2_lkup ), priority=110 , match=(inport == >> "vm-port" && ip4.dst == 10.0.0.1 && ip4.src == 10.0.0.10 && eth.dst == >> 00:00:00:00:01:01 && tcp.src == 80), action=(handle_svc_check(inport);) >>> +]) >>> + >>> +# type=external backend on prov (localnet LS): match keyed on >> flags.localnet >>> +# + eth.src, action borrows outport to load the backend tunnel_key into >>> +# MFF_LOG_INPORT for the controller dispatch. >>> +AT_CAPTURE_FILE([prov_lflows]) >>> +ovn-sbctl dump-flows prov | grep ls_in_l2_lkup | grep handle_svc_check \ >>> + > prov_lflows >>> +AT_CHECK([cat prov_lflows | ovn_strip_lflows], [0], [dnl >>> + table=??(ls_in_l2_lkup ), priority=110 , match=(eth.dst == >> $svc_monitor_mac && (tcp || icmp || icmp6)), >> action=(handle_svc_check(inport);) >>> + table=??(ls_in_l2_lkup ), priority=110 , match=(flags.localnet >> == 1 && eth.src == 00:00:00:00:02:0a && ip4.dst == 10.0.50.1 && ip4.src == >> 10.0.50.10 && eth.dst == 00:00:00:00:02:01 && tcp.src == 80), >> action=(outport = "bm-port"; handle_svc_check(outport); outport = "";) >>> +]) >>> + >>> +OVN_CLEANUP_NORTHD >>> +AT_CLEANUP >>> +]) >>> + >>> OVN_FOR_EACH_NORTHD_NO_HV([ >>> AT_SETUP([Load balancer VIP in NAT entries]) >>> AT_SKIP_IF([test $HAVE_PYTHON = no]) >>> -- >>> 2.49.0 >>> >> > _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
