On Tue, Apr 2, 2024 at 2:28 AM Ales Musil <amu...@redhat.com> wrote:
> The current packet injection loses ct_state in the process. When > the ct_state is lost we might commit to DNAT zone and perform > zero SNAT after the packet injection. This causes the first session > to be wrong as the reply packets are not unDNATted. > > Instead of re-injecting the packet back into the pipeline when > we get the MAC binding, use paused controller action. The paused > controller action stores ct_state, which is important for the behavior > of the resumed packet. > > At the same time bump the OvS submodule latest branch-3.3. This is > mainly for [0], which fixes metering for paused controller actions. > > [0] c560f6ca3257 ("ofproto-dpif-xlate: Fix continuations with associated > metering.") > > Reported-at: https://issues.redhat.com/browse/FDP-439 > Signed-off-by: Ales Musil <amu...@redhat.com> > Acked-by: Mark Michelson <mmich...@redhat.com> > --- > v2: Fix the Jira link and add ack from Mark. > Hi Ales, I see one problem during upgrades. The packet buffering functionality would be broken when ovn-controllers are updated to the version which has your patch but ovn-northd is still yet to. In this case, the below logical flow will be present (without the outer "output" action) --- table=21(lr_in_arp_request ), priority=100 , match=(eth.dst == 00:00:00:00:00:00 && ip4), action=(arp { eth.dst = ff:ff:ff:ff:ff:ff; arp.spa = reg1; arp.tpa = reg0; arp.op = 1; output; };) --- The updated ovn-controller will now resume the packet after learning the nexthop. But this resumed packet will be dropped because there is no "next" or "output" action following arp {}. Is this behavior acceptable until ovn-northd is also updated/upgraded ? Thanks Numan --- > controller/mac-learn.c | 30 +++++++++---- > controller/mac-learn.h | 9 ++-- > controller/pinctrl.c | 64 ++++++++++------------------ > lib/actions.c | 41 +++++++++++++++++- > northd/northd.c | 6 +-- > ovs | 2 +- > tests/ovn-northd.at | 3 ++ > tests/ovn.at | 8 ++-- > tests/system-ovn.at | 95 ++++++++++++++++++++++++++++++++++++++++++ > 9 files changed, 195 insertions(+), 63 deletions(-) > > diff --git a/controller/mac-learn.c b/controller/mac-learn.c > index 071f01b4f..0c3b60c23 100644 > --- a/controller/mac-learn.c > +++ b/controller/mac-learn.c > @@ -199,15 +199,24 @@ ovn_fdb_add(struct hmap *fdbs, uint32_t dp_key, > struct eth_addr mac, > /* packet buffering functions */ > > struct packet_data * > -ovn_packet_data_create(struct ofpbuf ofpacts, > - const struct dp_packet *original_packet) > +ovn_packet_data_create(const struct ofputil_packet_in *pin, > + const struct ofpbuf *continuation) > { > struct packet_data *pd = xmalloc(sizeof *pd); > > - pd->ofpacts = ofpacts; > - /* clone the packet to send it later with correct L2 address */ > - pd->p = dp_packet_clone_data(dp_packet_data(original_packet), > - dp_packet_size(original_packet)); > + pd->pin = (struct ofputil_packet_in) { > + .packet = xmemdup(pin->packet, pin->packet_len), > + .packet_len = pin->packet_len, > + .flow_metadata = pin->flow_metadata, > + .reason = pin->reason, > + .table_id = pin->table_id, > + .cookie = pin->cookie, > + /* Userdata are empty on purpose, > + * it is not needed for the continuation. */ > + .userdata = NULL, > + .userdata_len = 0, > + }; > + pd->continuation = ofpbuf_clone(continuation); > > return pd; > } > @@ -216,8 +225,8 @@ ovn_packet_data_create(struct ofpbuf ofpacts, > void > ovn_packet_data_destroy(struct packet_data *pd) > { > - dp_packet_delete(pd->p); > - ofpbuf_uninit(&pd->ofpacts); > + free(pd->pin.packet); > + ofpbuf_delete(pd->continuation); > free(pd); > } > > @@ -307,7 +316,10 @@ ovn_buffered_packets_ctx_run(struct > buffered_packets_ctx *ctx, > > struct packet_data *pd; > LIST_FOR_EACH_POP (pd, node, &bp->queue) { > - struct eth_header *eth = dp_packet_data(pd->p); > + struct dp_packet packet; > + dp_packet_use_const(&packet, pd->pin.packet, > pd->pin.packet_len); > + > + struct eth_header *eth = dp_packet_data(&packet); > eth->eth_dst = mac; > > ovs_list_push_back(&ctx->ready_packets_data, &pd->node); > diff --git a/controller/mac-learn.h b/controller/mac-learn.h > index e0fd6a8d1..20a015e1a 100644 > --- a/controller/mac-learn.h > +++ b/controller/mac-learn.h > @@ -24,6 +24,7 @@ > #include "openvswitch/hmap.h" > #include "openvswitch/list.h" > #include "openvswitch/ofpbuf.h" > +#include "openvswitch/ofp-packet.h" > > struct ovsdb_idl_index; > > @@ -91,8 +92,8 @@ struct fdb_entry *ovn_fdb_add(struct hmap *fdbs, > struct packet_data { > struct ovs_list node; > > - struct ofpbuf ofpacts; > - struct dp_packet *p; > + struct ofpbuf *continuation; > + struct ofputil_packet_in pin; > }; > > struct buffered_packets { > @@ -120,8 +121,8 @@ struct buffered_packets_ctx { > }; > > struct packet_data * > -ovn_packet_data_create(struct ofpbuf ofpacts, > - const struct dp_packet *original_packet); > +ovn_packet_data_create(const struct ofputil_packet_in *pin, > + const struct ofpbuf *continuation); > void ovn_packet_data_destroy(struct packet_data *pd); > struct buffered_packets * > ovn_buffered_packets_add(struct buffered_packets_ctx *ctx, uint64_t > dp_key, > diff --git a/controller/pinctrl.c b/controller/pinctrl.c > index 9a4deb80a..2c0ecdb4c 100644 > --- a/controller/pinctrl.c > +++ b/controller/pinctrl.c > @@ -258,9 +258,9 @@ static void pinctrl_handle_put_nd_ra_opts( > struct ofpbuf *continuation); > static void pinctrl_handle_nd_ns(struct rconn *swconn, > const struct flow *ip_flow, > - struct dp_packet *pkt_in, > - const struct match *md, > - struct ofpbuf *userdata); > + const struct ofputil_packet_in *pin, > + struct ofpbuf *userdata, > + const struct ofpbuf *continuation); > static void pinctrl_handle_put_icmp_frag_mtu(struct rconn *swconn, > const struct flow *in_flow, > struct dp_packet *pkt_in, > @@ -1534,11 +1534,13 @@ destroy_buffered_packets_ctx(void) > > /* Called with in the pinctrl_handler thread context. */ > static void > -pinctrl_handle_buffered_packets(struct dp_packet *pkt_in, > - const struct match *md, bool is_arp) > +pinctrl_handle_buffered_packets(const struct ofputil_packet_in *pin, > + const struct ofpbuf *continuation, > + bool is_arp) > OVS_REQUIRES(pinctrl_mutex) > { > struct in6_addr ip; > + const struct match *md = &pin->flow_metadata; > uint64_t dp_key = ntohll(md->flow.metadata); > uint64_t oport_key = md->flow.regs[MFF_LOG_OUTPORT - MFF_REG0]; > > @@ -1556,20 +1558,7 @@ OVS_REQUIRES(pinctrl_mutex) > return; > } > > - struct ofpbuf ofpacts; > - ofpbuf_init(&ofpacts, 4096); > - reload_metadata(&ofpacts, md); > - /* reload pkt_mark field */ > - const struct mf_field *pkt_mark_field = mf_from_id(MFF_PKT_MARK); > - union mf_value pkt_mark_value; > - mf_get_value(pkt_mark_field, &md->flow, &pkt_mark_value); > - ofpact_put_set_field(&ofpacts, pkt_mark_field, &pkt_mark_value, NULL); > - > - struct ofpact_resubmit *resubmit = ofpact_put_RESUBMIT(&ofpacts); > - resubmit->in_port = OFPP_CONTROLLER; > - resubmit->table_id = OFTABLE_OUTPUT_INIT; > - > - struct packet_data *pd = ovn_packet_data_create(ofpacts, pkt_in); > + struct packet_data *pd = ovn_packet_data_create(pin, continuation); > ovn_buffered_packets_packet_data_enqueue(bp, pd); > > /* There is a chance that the MAC binding was already created. */ > @@ -1579,8 +1568,8 @@ OVS_REQUIRES(pinctrl_mutex) > /* Called with in the pinctrl_handler thread context. */ > static void > pinctrl_handle_arp(struct rconn *swconn, const struct flow *ip_flow, > - struct dp_packet *pkt_in, > - const struct match *md, struct ofpbuf *userdata) > + const struct ofputil_packet_in *pin, > + struct ofpbuf *userdata, const struct ofpbuf > *continuation) > { > /* This action only works for IP packets, and the switch should only > send > * us IP packets this way, but check here just to be sure. */ > @@ -1592,7 +1581,7 @@ pinctrl_handle_arp(struct rconn *swconn, const > struct flow *ip_flow, > } > > ovs_mutex_lock(&pinctrl_mutex); > - pinctrl_handle_buffered_packets(pkt_in, md, true); > + pinctrl_handle_buffered_packets(pin, continuation, true); > ovs_mutex_unlock(&pinctrl_mutex); > > /* Compose an ARP packet. */ > @@ -1617,7 +1606,8 @@ pinctrl_handle_arp(struct rconn *swconn, const > struct flow *ip_flow, > ip_flow->vlans[0].tci); > } > > - set_actions_and_enqueue_msg(swconn, &packet, md, userdata); > + set_actions_and_enqueue_msg(swconn, &packet, > + &pin->flow_metadata, userdata); > dp_packet_uninit(&packet); > } > > @@ -3294,8 +3284,7 @@ process_packet_in(struct rconn *swconn, const struct > ofp_header *msg) > > switch (ntohl(ah->opcode)) { > case ACTION_OPCODE_ARP: > - pinctrl_handle_arp(swconn, &headers, &packet, &pin.flow_metadata, > - &userdata); > + pinctrl_handle_arp(swconn, &headers, &pin, &userdata, > &continuation); > break; > case ACTION_OPCODE_IGMP: > pinctrl_ip_mcast_handle(swconn, &headers, &packet, > &pin.flow_metadata, > @@ -3361,8 +3350,7 @@ process_packet_in(struct rconn *swconn, const struct > ofp_header *msg) > break; > > case ACTION_OPCODE_ND_NS: > - pinctrl_handle_nd_ns(swconn, &headers, &packet, > &pin.flow_metadata, > - &userdata); > + pinctrl_handle_nd_ns(swconn, &headers, &pin, &userdata, > &continuation); > break; > > case ACTION_OPCODE_ICMP: > @@ -4374,16 +4362,8 @@ send_mac_binding_buffered_pkts(struct rconn *swconn) > > struct packet_data *pd; > LIST_FOR_EACH_POP (pd, node, > &buffered_packets_ctx.ready_packets_data) { > - struct ofputil_packet_out po = { > - .packet = dp_packet_data(pd->p), > - .packet_len = dp_packet_size(pd->p), > - .buffer_id = UINT32_MAX, > - .ofpacts = pd->ofpacts.data, > - .ofpacts_len = pd->ofpacts.size, > - }; > - match_set_in_port(&po.flow_metadata, OFPP_CONTROLLER); > - queue_msg(swconn, ofputil_encode_packet_out(&po, proto)); > - > + queue_msg(swconn, ofputil_encode_resume(&pd->pin, > pd->continuation, > + proto)); > ovn_packet_data_destroy(pd); > } > > @@ -6317,8 +6297,9 @@ pinctrl_handle_nd_na(struct rconn *swconn, const > struct flow *ip_flow, > /* Called with in the pinctrl_handler thread context. */ > static void > pinctrl_handle_nd_ns(struct rconn *swconn, const struct flow *ip_flow, > - struct dp_packet *pkt_in, > - const struct match *md, struct ofpbuf *userdata) > + const struct ofputil_packet_in *pin, > + struct ofpbuf *userdata, > + const struct ofpbuf *continuation) > { > /* This action only works for IPv6 packets. */ > if (get_dl_type(ip_flow) != htons(ETH_TYPE_IPV6)) { > @@ -6328,7 +6309,7 @@ pinctrl_handle_nd_ns(struct rconn *swconn, const > struct flow *ip_flow, > } > > ovs_mutex_lock(&pinctrl_mutex); > - pinctrl_handle_buffered_packets(pkt_in, md, false); > + pinctrl_handle_buffered_packets(pin, continuation, false); > ovs_mutex_unlock(&pinctrl_mutex); > > uint64_t packet_stub[128 / 8]; > @@ -6341,7 +6322,8 @@ pinctrl_handle_nd_ns(struct rconn *swconn, const > struct flow *ip_flow, > &ip_flow->ipv6_dst); > > /* Reload previous packet metadata and set actions from userdata. */ > - set_actions_and_enqueue_msg(swconn, &packet, md, userdata); > + set_actions_and_enqueue_msg(swconn, &packet, > + &pin->flow_metadata, userdata); > dp_packet_uninit(&packet); > } > > diff --git a/lib/actions.c b/lib/actions.c > index 71615fc53..004b77a89 100644 > --- a/lib/actions.c > +++ b/lib/actions.c > @@ -1977,6 +1977,44 @@ format_REJECT(const struct ovnact_nest *nest, > struct ds *s) > format_nested_action(nest, "reject", s); > } > > +static bool > +is_paused_nested_action(enum action_opcode opcode) > +{ > + switch (opcode) { > + case ACTION_OPCODE_ARP: > + case ACTION_OPCODE_ND_NS: > + return true; > + case ACTION_OPCODE_IGMP: > + case ACTION_OPCODE_PUT_ARP: > + case ACTION_OPCODE_PUT_DHCP_OPTS: > + case ACTION_OPCODE_ND_NA: > + case ACTION_OPCODE_ND_NA_ROUTER: > + case ACTION_OPCODE_PUT_ND: > + case ACTION_OPCODE_PUT_FDB: > + case ACTION_OPCODE_PUT_DHCPV6_OPTS: > + case ACTION_OPCODE_DNS_LOOKUP: > + case ACTION_OPCODE_LOG: > + case ACTION_OPCODE_PUT_ND_RA_OPTS: > + case ACTION_OPCODE_ICMP: > + case ACTION_OPCODE_ICMP4_ERROR: > + case ACTION_OPCODE_ICMP6_ERROR: > + case ACTION_OPCODE_TCP_RESET: > + case ACTION_OPCODE_SCTP_ABORT: > + case ACTION_OPCODE_REJECT: > + case ACTION_OPCODE_PUT_ICMP4_FRAG_MTU: > + case ACTION_OPCODE_PUT_ICMP6_FRAG_MTU: > + case ACTION_OPCODE_EVENT: > + case ACTION_OPCODE_BIND_VPORT: > + case ACTION_OPCODE_DHCP6_SERVER: > + case ACTION_OPCODE_HANDLE_SVC_CHECK: > + case ACTION_OPCODE_BFD_MSG: > + case ACTION_OPCODE_ACTIVATION_STRATEGY_RARP: > + case ACTION_OPCODE_MG_SPLIT_BUF: > + default: > + return false; > + } > +} > + > static void > encode_nested_actions(const struct ovnact_nest *on, > const struct ovnact_encode_params *ep, > @@ -1992,7 +2030,8 @@ encode_nested_actions(const struct ovnact_nest *on, > * converted to OpenFlow, as its userdata. ovn-controller will > convert the > * packet to ARP or NA and then send the packet and actions back to > the > * switch inside an OFPT_PACKET_OUT message. */ > - size_t oc_offset = encode_start_controller_op(opcode, false, > + bool pause = is_paused_nested_action(opcode); > + size_t oc_offset = encode_start_controller_op(opcode, pause, > ep->ctrl_meter_id, > ofpacts); > ofpacts_put_openflow_actions(inner_ofpacts.data, inner_ofpacts.size, > ofpacts, OFP15_VERSION); > diff --git a/northd/northd.c b/northd/northd.c > index c568f6360..f65f0d1d9 100644 > --- a/northd/northd.c > +++ b/northd/northd.c > @@ -13427,7 +13427,7 @@ build_arp_request_flows_for_lrouter( > "ip6.dst = %s; " > "nd.target = %s; " > "output; " > - "};", ETH_ADDR_ARGS(eth_dst), sn_addr_s, > + "}; output;", ETH_ADDR_ARGS(eth_dst), sn_addr_s, > route->nexthop); > > ovn_lflow_add_with_hint__(lflows, od, S_ROUTER_IN_ARP_REQUEST, > 200, > @@ -13447,7 +13447,7 @@ build_arp_request_flows_for_lrouter( > "arp.tpa = " REG_NEXT_HOP_IPV4 "; " > "arp.op = 1; " /* ARP request */ > "output; " > - "};", > + "}; output;", > copp_meter_get(COPP_ARP_RESOLVE, od->nbr->copp, > meter_groups), > lflow_ref); > @@ -13456,7 +13456,7 @@ build_arp_request_flows_for_lrouter( > "nd_ns { " > "nd.target = " REG_NEXT_HOP_IPV6 "; " > "output; " > - "};", > + "}; output;", > copp_meter_get(COPP_ND_NS_RESOLVE, od->nbr->copp, > meter_groups), > lflow_ref); > diff --git a/ovs b/ovs > index fe55ce37a..43db93787 160000 > --- a/ovs > +++ b/ovs > @@ -1 +1 @@ > -Subproject commit fe55ce37a7b090d09dee5c01ae0797320ad678f6 > +Subproject commit 43db937876fcec57947634d6e642429673d1ec06 > diff --git a/tests/ovn-northd.at b/tests/ovn-northd.at > index cd53755b2..b3f8bd158 100644 > --- a/tests/ovn-northd.at > +++ b/tests/ovn-northd.at > @@ -6947,6 +6947,9 @@ ct_dnat /* assuming no un-dnat entry, so no change > */ { > arp.op = 1; > output("rtr-ls"); > }; > + ct_dnat /* assuming no un-dnat entry, so no change */ { > + output("rtr-ls"); > + }; > }; > }; > ]) > diff --git a/tests/ovn.at b/tests/ovn.at > index dd2ebce98..471cafcf9 100644 > --- a/tests/ovn.at > +++ b/tests/ovn.at > @@ -1540,11 +1540,11 @@ clone { ip4.dst = 255.255.255.255; output; }; next; > > # arp > arp { eth.dst = ff:ff:ff:ff:ff:ff; output; }; output; > - encodes as > controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.OFTABLE_SAVE_INPORT_HEX.00.00.00),resubmit(,OFTABLE_SAVE_INPORT) > + encodes as > controller(userdata=00.00.00.00.00.00.00.00.00.19.00.10.80.00.06.06.ff.ff.ff.ff.ff.ff.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.OFTABLE_SAVE_INPORT_HEX.00.00.00,pause),resubmit(,OFTABLE_SAVE_INPORT) > has prereqs ip4 > arp { }; > formats as arp { drop; }; > - encodes as controller(userdata=00.00.00.00.00.00.00.00) > + encodes as controller(userdata=00.00.00.00.00.00.00.00,pause) > has prereqs ip4 > > # get_arp > @@ -1674,12 +1674,12 @@ reg1[[0]] = put_dhcp_opts(offerip=1.2.3.4, > domain_search_list=1.2.3.4); > > # nd_ns > nd_ns { nd.target = xxreg0; output; }; > - encodes as controller(userdata=00.00.00.09.00.00.00.00.00.1c.00.18.00. > 80.00.00.00.00.00.00.00.01.de > .10.80.00.3e.10.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.OFTABLE_SAVE_INPORT_HEX.00.00.00) > + encodes as controller(userdata=00.00.00.09.00.00.00.00.00.1c.00.18.00. > 80.00.00.00.00.00.00.00.01.de > .10.80.00.3e.10.00.00.00.00.ff.ff.00.10.00.00.23.20.00.0e.ff.f8.OFTABLE_SAVE_INPORT_HEX.00.00.00,pause) > has prereqs ip6 > > nd_ns { }; > formats as nd_ns { drop; }; > - encodes as controller(userdata=00.00.00.09.00.00.00.00) > + encodes as controller(userdata=00.00.00.09.00.00.00.00,pause) > has prereqs ip6 > > # nd_na > diff --git a/tests/system-ovn.at b/tests/system-ovn.at > index fc69facb9..c69e649a6 100644 > --- a/tests/system-ovn.at > +++ b/tests/system-ovn.at > @@ -12298,3 +12298,98 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port > patch-.*/d > /connection dropped.*/d"]) > AT_CLEANUP > ]) > + > +OVN_FOR_EACH_NORTHD([ > +AT_SETUP([LB with first packet buffered]) > +AT_KEYWORDS([ovnlb]) > + > +CHECK_CONNTRACK() > +CHECK_CONNTRACK_NAT() > + > +ovn_start > +OVS_TRAFFIC_VSWITCHD_START() > +ADD_BR([br-int]) > +ADD_BR([br-ext]) > + > +check ovs-ofctl add-flow br-ext action=normal > +# Set external-ids in br-int needed for ovn-controller > +check ovs-vsctl \ > + -- set Open_vSwitch . external-ids:system-id=hv1 \ > + -- set Open_vSwitch . > external-ids:ovn-remote=unix:$ovs_base/ovn-sb/ovn-sb.sock \ > + -- set Open_vSwitch . external-ids:ovn-encap-type=geneve \ > + -- set Open_vSwitch . external-ids:ovn-encap-ip=169.0.0.1 \ > + -- set bridge br-int fail-mode=secure > other-config:disable-in-band=true \ > + -- set Open_vSwitch . > external-ids:ovn-bridge-mappings=phynet:br-ext > + > +# Start ovn-controller > +start_daemon ovn-controller > + > +check ovn-nbctl lr-add lr > +check ovn-nbctl ls-add internal > +check ovn-nbctl ls-add public > + > +check ovn-nbctl lrp-add lr lr-pub 00:00:01:01:02:03 192.168.100.1/24 > 1000::1/64 > +check ovn-nbctl lsp-add public pub-lr -- set Logical_Switch_Port pub-lr \ > + type=router options:router-port=lr-pub addresses=\"00:00:01:01:02:03\" > + > +check ovn-nbctl lrp-add lr lr-internal 00:00:01:01:02:04 192.168.200.1/24 > 2000::1/64 > +check ovn-nbctl lsp-add internal internal-lr -- set Logical_Switch_Port > internal-lr \ > + type=router options:router-port=lr-internal > addresses=\"00:00:01:01:02:04\" > + > +check ovn-nbctl lsp-add internal server -- lsp-set-addresses server > "unknown" > + > +ovn-nbctl lsp-add public ln_port \ > + -- lsp-set-addresses ln_port unknown \ > + -- lsp-set-type ln_port localnet \ > + -- lsp-set-options ln_port network_name=phynet > + > +check ovn-nbctl set logical_router lr options:chassis=hv1 > + > +check ovn-nbctl lb-add lb1 192.168.100.20 192.168.200.10 > +check ovn-nbctl lb-add lb2 1000::20 2000::10 > +check ovn-nbctl lr-lb-add lr lb1 > +check ovn-nbctl lr-lb-add lr lb2 > +check ovn-nbctl --wait=hv sync > + > +ADD_NAMESPACES(client) > +ADD_VETH(client, client, br-ext, "1000::10/64", "f0:00:00:01:02:03", \ > + "1000::1", "nodad", "192.168.100.10/24", "192.168.100.1") > + > +ADD_NAMESPACES(server) > +ADD_VETH(server, server, br-int, "2000::10/64", "f0:00:0f:01:02:03", \ > + "2000::1", "nodad", "192.168.200.10/24", "192.168.200.1") > + > +NETNS_DAEMONIZE([server], [nc -l -u 192.168.200.10 4242 > /dev/null], > [serverv4.pid]) > +NETNS_DAEMONIZE([server], [nc -l -u 2000::10 4243 > /dev/null], > [serverv6.pid]) > + > +NETNS_START_TCPDUMP([client], [-l -U -i client -vnne udp], [client]) > +NETNS_START_TCPDUMP([server], [-l -U -i server -vnne udp], [server]) > + > +check ovs-appctl dpctl/flush-conntrack > + > +NS_CHECK_EXEC([client], [nc -z -u 192.168.100.20 4242], [ignore], > [ignore], [ignore]) > +OVS_WAIT_UNTIL([grep -q "192.168.200.10" server.tcpdump]) > + > +NS_CHECK_EXEC([client], [nc -z -u 1000::20 4243]) > +OVS_WAIT_UNTIL([grep -q "2000::10" server.tcpdump]) > + > +zone_id=$(ovn-appctl -t ovn-controller ct-zone-list | grep lr_dnat | cut > -d ' ' -f2) > +AT_CHECK([ovs-appctl dpctl/dump-conntrack | grep -c "zone=$zone_id"], > [0], [2 > +]) > + > +OVS_APP_EXIT_AND_WAIT([ovn-controller]) > + > +as ovn-sb > +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) > + > +as ovn-nb > +OVS_APP_EXIT_AND_WAIT([ovsdb-server]) > + > +as northd > +OVS_APP_EXIT_AND_WAIT([ovn-northd]) > + > +as > +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d > +/connection dropped.*/d"]) > +AT_CLEANUP > +]) > -- > 2.44.0 > > _______________________________________________ > dev mailing list > d...@openvswitch.org > https://mail.openvswitch.org/mailman/listinfo/ovs-dev > > _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev