Remove CT for LB backends that are affected by any LB change. This way there shouldn't be any stale entry in the CT. This feature is enabled by default but is dependent on OvS support for CT flush via OFP extension.
Reported-at: https://bugzilla.redhat.com/1839103 Signed-off-by: Ales Musil <[email protected]> --- v2: Rebase on top of current main. Address comments from Dumitru: - Rename the struct to ovn_lb_5tuple - Encapsulate the 5tuple related functions more in lb.h/.c --- controller/ofctrl.c | 41 ++++++++ controller/ofctrl.h | 1 + controller/ovn-controller.c | 54 +++++++++- include/ovn/features.h | 2 + lib/features.c | 5 + lib/lb.c | 86 ++++++++++++++++ lib/lb.h | 21 ++++ tests/ovn.at | 65 ++++++++++++ tests/system-ovn.at | 190 ++++++++++++++++++++++++++++++++++++ 9 files changed, 464 insertions(+), 1 deletion(-) diff --git a/controller/ofctrl.c b/controller/ofctrl.c index 6c631ea41..b1ba1c743 100644 --- a/controller/ofctrl.c +++ b/controller/ofctrl.c @@ -30,6 +30,7 @@ #include "openvswitch/match.h" #include "openvswitch/ofp-actions.h" #include "openvswitch/ofp-bundle.h" +#include "openvswitch/ofp-ct.h" #include "openvswitch/ofp-flow.h" #include "openvswitch/ofp-group.h" #include "openvswitch/ofp-match.h" @@ -43,6 +44,7 @@ #include "ovn-controller.h" #include "ovn/actions.h" #include "lib/extend-table.h" +#include "lib/lb.h" #include "openvswitch/poll-loop.h" #include "physical.h" #include "openvswitch/rconn.h" @@ -2485,6 +2487,36 @@ update_installed_flows_by_track(struct ovn_desired_flow_table *flow_table, } } +static void +add_ct_flush_tuple(const struct ovn_lb_5tuple *tuple, + struct ovs_list *msgs) +{ + if (VLOG_IS_DBG_ENABLED()) { + struct ds ds = DS_EMPTY_INITIALIZER; + + ds_put_cstr(&ds, "Flushing CT for 5-tuple: vip="); + ipv6_format_mapped(&tuple->vip_ip, &ds); + ds_put_format(&ds, ":%"PRIu16", backend=", tuple->vip_port); + ipv6_format_mapped(&tuple->backend_ip, &ds); + ds_put_format(&ds, ":%"PRIu16", protocol=%"PRIu8, + tuple->backend_port, tuple->proto); + VLOG_DBG("%s", ds_cstr(&ds)); + + ds_destroy(&ds); + } + + struct ofp_ct_match match = { + .ip_proto = tuple->proto, + .tuple_orig.dst = tuple->vip_ip, + .tuple_orig.dst_port = htons(tuple->vip_port), + .tuple_reply.src = tuple->backend_ip, + .tuple_reply.src_port = htons(tuple->backend_port), + }; + + struct ofpbuf *msg = ofp_ct_match_encode(&match, NULL, OFP15_VERSION); + ovs_list_push_back(msgs, &msg->list_node); +} + bool ofctrl_has_backlog(void) { @@ -2524,6 +2556,7 @@ void ofctrl_put(struct ovn_desired_flow_table *lflow_table, struct ovn_desired_flow_table *pflow_table, struct shash *pending_ct_zones, + struct hmap *pending_lb_tuples, const struct sbrec_meter_table *meter_table, uint64_t req_cfg, bool lflows_changed, @@ -2754,6 +2787,14 @@ ofctrl_put(struct ovn_desired_flow_table *lflow_table, /* Sync the contents of meters->desired to meters->existing. */ ovn_extend_table_sync(meters); + if (ovs_feature_is_supported(OVS_CT_TUPLE_FLUSH_SUPPORT)) { + struct ovn_lb_5tuple *tuple; + HMAP_FOR_EACH_POP (tuple, hmap_node, pending_lb_tuples) { + add_ct_flush_tuple(tuple, &msgs); + free(tuple); + } + } + if (!ovs_list_is_empty(&msgs)) { /* Add a barrier to the list of messages. */ struct ofpbuf *barrier = ofputil_encode_barrier_request(OFP15_VERSION); diff --git a/controller/ofctrl.h b/controller/ofctrl.h index 396824512..f5751e3ee 100644 --- a/controller/ofctrl.h +++ b/controller/ofctrl.h @@ -58,6 +58,7 @@ enum mf_field_id ofctrl_get_mf_field_id(void); void ofctrl_put(struct ovn_desired_flow_table *lflow_table, struct ovn_desired_flow_table *pflow_table, struct shash *pending_ct_zones, + struct hmap *pending_lb_tuples, const struct sbrec_meter_table *, uint64_t nb_cfg, bool lflow_changed, diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c index d96f16cc2..6d2003fd3 100644 --- a/controller/ovn-controller.c +++ b/controller/ovn-controller.c @@ -2667,6 +2667,8 @@ load_balancers_by_dp_cleanup(struct hmap *lbs) struct ed_type_lb_data { /* Locally installed 'struct ovn_controller_lb' by UUID. */ struct hmap local_lbs; + /* 'struct ovn_lb_five_tuple' removed during last run. */ + struct hmap removed_tuples; /* Load balancer <-> resource cross reference */ struct objdep_mgr deps_mgr; /* Objects processed in the current engine execution. @@ -2691,6 +2693,46 @@ struct lb_data_ctx_in { const struct smap *template_vars; }; +static void +lb_data_removed_five_tuples_add(struct ed_type_lb_data *lb_data, + const struct ovn_controller_lb *lb) +{ + if (!ovs_feature_is_supported(OVS_CT_TUPLE_FLUSH_SUPPORT)) { + return; + } + + for (size_t i = 0; i < lb->n_vips; i++) { + struct ovn_lb_vip *vip = &lb->vips[i]; + for (size_t j = 0; j < vip->n_backends; j++) { + struct ovn_lb_backend *backend = &vip->backends[j]; + + ovn_lb_5tuple_add(&lb_data->removed_tuples, vip, backend, + lb->proto); + } + } +} + +static void +lb_data_removed_five_tuples_remove(struct ed_type_lb_data *lb_data, + const struct ovn_controller_lb *lb) +{ + if (!ovs_feature_is_supported(OVS_CT_TUPLE_FLUSH_SUPPORT)) { + return; + } + + for (size_t i = 0; i < lb->n_vips; i++) { + struct ovn_lb_vip *vip = &lb->vips[i]; + for (size_t j = 0; j < vip->n_backends; j++) { + struct ovn_lb_backend *backend = &vip->backends[j]; + + + struct ovn_lb_5tuple tuple; + ovn_lb_5tuple_init(&tuple, vip, backend, lb->proto); + ovn_lb_5tuple_find_and_delete(&lb_data->removed_tuples, &tuple); + } + } +} + static void lb_data_local_lb_add(struct ed_type_lb_data *lb_data, const struct sbrec_load_balancer *sbrec_lb, @@ -2711,6 +2753,8 @@ lb_data_local_lb_add(struct ed_type_lb_data *lb_data, sset_destroy(&template_vars_ref); + lb_data_removed_five_tuples_remove(lb_data, lb); + if (!tracked) { return; } @@ -2732,6 +2776,8 @@ lb_data_local_lb_remove(struct ed_type_lb_data *lb_data, objdep_mgr_remove_obj(&lb_data->deps_mgr, uuid); hmap_remove(&lb_data->local_lbs, &lb->hmap_node); + lb_data_removed_five_tuples_add(lb_data, lb); + if (tracked) { hmap_insert(&lb_data->old_lbs, &lb->hmap_node, uuid_hash(uuid)); uuidset_insert(&lb_data->deleted, uuid); @@ -2785,6 +2831,7 @@ en_lb_data_init(struct engine_node *node OVS_UNUSED, struct ed_type_lb_data *lb_data = xzalloc(sizeof *lb_data); hmap_init(&lb_data->local_lbs); + hmap_init(&lb_data->removed_tuples); objdep_mgr_init(&lb_data->deps_mgr); uuidset_init(&lb_data->objs_processed); lb_data->change_tracked = false; @@ -3025,6 +3072,7 @@ en_lb_data_cleanup(void *data) struct ed_type_lb_data *lb_data = data; ovn_controller_lbs_destroy(&lb_data->local_lbs); + ovn_lb_5tuples_destroy(&lb_data->removed_tuples); objdep_mgr_destroy(&lb_data->deps_mgr); uuidset_destroy(&lb_data->objs_processed); ovn_controller_lbs_destroy(&lb_data->old_lbs); @@ -4797,6 +4845,8 @@ main(int argc, char *argv[]) engine_get_internal_data(&en_runtime_data); struct ed_type_template_vars *template_vars_data = engine_get_internal_data(&en_template_vars); + struct ed_type_lb_data *lb_data = + engine_get_internal_data(&en_lb_data); ofctrl_init(&lflow_output_data->group_table, &lflow_output_data->meter_table, @@ -5195,13 +5245,15 @@ main(int argc, char *argv[]) lflow_output_data = engine_get_data(&en_lflow_output); pflow_output_data = engine_get_data(&en_pflow_output); + lb_data = engine_get_data(&en_lb_data); if (lflow_output_data && pflow_output_data && - ct_zones_data) { + ct_zones_data && lb_data) { stopwatch_start(OFCTRL_PUT_STOPWATCH_NAME, time_msec()); ofctrl_put(&lflow_output_data->flow_table, &pflow_output_data->flow_table, &ct_zones_data->pending, + &lb_data->removed_tuples, sbrec_meter_table_get(ovnsb_idl_loop.idl), ofctrl_seqno_get_req_cfg(), engine_node_changed(&en_lflow_output), diff --git a/include/ovn/features.h b/include/ovn/features.h index 5bcd68739..a37daa4c8 100644 --- a/include/ovn/features.h +++ b/include/ovn/features.h @@ -32,11 +32,13 @@ enum ovs_feature_support_bits { OVS_CT_ZERO_SNAT_SUPPORT_BIT, OVS_DP_METER_SUPPORT_BIT, + OVS_CT_TUPLE_FLUSH_BIT, }; enum ovs_feature_value { OVS_CT_ZERO_SNAT_SUPPORT = (1 << OVS_CT_ZERO_SNAT_SUPPORT_BIT), OVS_DP_METER_SUPPORT = (1 << OVS_DP_METER_SUPPORT_BIT), + OVS_CT_TUPLE_FLUSH_SUPPORT = (1 << OVS_CT_TUPLE_FLUSH_BIT), }; void ovs_feature_support_destroy(void); diff --git a/lib/features.c b/lib/features.c index 462b99818..97c9c86f0 100644 --- a/lib/features.c +++ b/lib/features.c @@ -43,6 +43,10 @@ static struct ovs_feature all_ovs_features[] = { .value = OVS_CT_ZERO_SNAT_SUPPORT, .name = "ct_zero_snat" }, + { + .value = OVS_CT_TUPLE_FLUSH_SUPPORT, + .name = "ct_flush" + } }; /* A bitmap of OVS features that have been detected as 'supported'. */ @@ -60,6 +64,7 @@ ovs_feature_is_valid(enum ovs_feature_value feature) switch (feature) { case OVS_CT_ZERO_SNAT_SUPPORT: case OVS_DP_METER_SUPPORT: + case OVS_CT_TUPLE_FLUSH_SUPPORT: return true; default: return false; diff --git a/lib/lb.c b/lib/lb.c index de25c68c0..b0ed59861 100644 --- a/lib/lb.c +++ b/lib/lb.c @@ -496,6 +496,24 @@ ovn_lb_get_health_check(const struct nbrec_load_balancer *nbrec_lb, return NULL; } +static inline uint32_t +hash_add_in6_addr(uint32_t hash, const struct in6_addr *addr) +{ + for (uint8_t i = 0; i < 4; i++) { +#ifdef s6_addr32 + hash = hash_add(hash, addr->s6_addr32[i]); +#else + uint8_t index = i * 4; + uint32_t part = (uint32_t) addr->s6_addr[index] + | (uint32_t) addr->s6_addr[index + 1] << 8 + | (uint32_t) addr->s6_addr[index + 2] << 16 + | (uint32_t) addr->s6_addr[index + 3] << 24; + hash = hash_add(hash, part); +#endif + } + return hash; +} + struct ovn_northd_lb * ovn_northd_lb_create(const struct nbrec_load_balancer *nbrec_lb, size_t n_datapaths) @@ -798,3 +816,71 @@ ovn_controller_lb_find(const struct hmap *ovn_controller_lbs, } return NULL; } + +static uint32_t +ovn_lb_5tuple_hash(const struct ovn_lb_5tuple *tuple) +{ + uint32_t hash = 0; + + hash = hash_add_in6_addr(hash, &tuple->vip_ip); + hash = hash_add_in6_addr(hash, &tuple->backend_ip); + + hash = hash_add(hash, tuple->vip_port); + hash = hash_add(hash, tuple->backend_port); + + hash = hash_add(hash, tuple->proto); + + return hash_finish(hash, 0); + +} + +void +ovn_lb_5tuple_init(struct ovn_lb_5tuple *tuple, const struct ovn_lb_vip *vip, + const struct ovn_lb_backend *backend, uint8_t proto) +{ + tuple->vip_ip = vip->vip; + tuple->vip_port = vip->vip_port; + tuple->backend_ip = backend->ip; + tuple->backend_port = backend->port; + tuple->proto = vip->vip_port ? proto : 0; +} + +void +ovn_lb_5tuple_add(struct hmap *tuples, const struct ovn_lb_vip *vip, + const struct ovn_lb_backend *backend, uint8_t proto) +{ + struct ovn_lb_5tuple *tuple = xmalloc(sizeof *tuple); + ovn_lb_5tuple_init(tuple, vip, backend, proto); + hmap_insert(tuples, &tuple->hmap_node, ovn_lb_5tuple_hash(tuple)); +} + +void +ovn_lb_5tuple_find_and_delete(struct hmap *tuples, + const struct ovn_lb_5tuple *tuple) +{ + uint32_t hash = ovn_lb_5tuple_hash(tuple); + + struct ovn_lb_5tuple *node; + HMAP_FOR_EACH_WITH_HASH (node, hmap_node, hash, tuples) { + if (ipv6_addr_equals(&tuple->vip_ip, &node->vip_ip) && + ipv6_addr_equals(&tuple->backend_ip, &node->backend_ip) && + tuple->vip_port == node->vip_port && + tuple->backend_port == node->backend_port && + tuple->proto == node->proto) { + hmap_remove(tuples, &node->hmap_node); + free(node); + return; + } + } +} + +void +ovn_lb_5tuples_destroy(struct hmap *tuples) +{ + struct ovn_lb_5tuple *tuple; + HMAP_FOR_EACH_POP (tuple, hmap_node, tuples) { + free(tuple); + } + + hmap_destroy(tuples); +} diff --git a/lib/lb.h b/lib/lb.h index f32891ea6..724189572 100644 --- a/lib/lb.h +++ b/lib/lb.h @@ -208,4 +208,25 @@ void ovn_lb_vip_format(const struct ovn_lb_vip *vip, struct ds *s, void ovn_lb_vip_backends_format(const struct ovn_lb_vip *vip, struct ds *s, bool template); +struct ovn_lb_5tuple { + struct hmap_node hmap_node; + + struct in6_addr vip_ip; + uint16_t vip_port; + + struct in6_addr backend_ip; + uint16_t backend_port; + + uint8_t proto; +}; + +void ovn_lb_5tuple_init(struct ovn_lb_5tuple *tuple, + const struct ovn_lb_vip *vip, + const struct ovn_lb_backend *backend, uint8_t proto); +void ovn_lb_5tuple_add(struct hmap *tuples, const struct ovn_lb_vip *vip, + const struct ovn_lb_backend *backend, uint8_t proto); +void ovn_lb_5tuple_find_and_delete(struct hmap *tuples, + const struct ovn_lb_5tuple *tuple); +void ovn_lb_5tuples_destroy(struct hmap *tuples); + #endif /* OVN_LIB_LB_H 1 */ diff --git a/tests/ovn.at b/tests/ovn.at index dd9985179..d7953ae49 100644 --- a/tests/ovn.at +++ b/tests/ovn.at @@ -34700,3 +34700,68 @@ check_packets OVN_CLEANUP([hv1]) AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([CT flush load balancer backends]) +ovn_start +net_add n1 + +sim_add hv1 +as hv1 +ovs-vsctl add-br br-phys +ovn_attach n1 br-phys 192.168.0.1 + +check ovn-appctl vlog/set ofctrl:dbg + +check ovn-nbctl ls-add sw +check ovn-nbctl lsp-add sw lsp1 +check ovs-vsctl add-port br-int p1 -- set interface p1 external_ids:iface-id=lsp1 + +wait_for_ports_up +ovn-nbctl --wait=hv sync + +check ovn-nbctl lb-add lb1 "192.168.0.10" "192.168.10.10,192.168.10.20" +check ovn-nbctl ls-lb-add sw lb1 + +# Remove a single backend +check ovn-nbctl set load_balancer lb1 vips='"192.168.0.10"="192.168.10.10"' +check ovn-nbctl --wait=hv sync + +AT_CHECK([grep -q "Flushing CT for 5-tuple: vip=192.168.0.10:0, backend=192.168.10.20:0, protocol=0" hv1/ovn-controller.log], [0]) + +# Add a new backend (there shouldn't be any flush) +check ovn-nbctl set load_balancer lb1 vips='"192.168.0.10"="192.168.10.10,192.168.10.30"' +check ovn-nbctl --wait=hv sync + +AT_CHECK([test "$(grep -c "Flushing CT for 5-tuple" hv1/ovn-controller.log)" = "1"], [0]) + +# Remove the whole LB +check ovn-nbctl lb-del lb1 +check ovn-nbctl --wait=hv sync + +AT_CHECK([grep -q "Flushing CT for 5-tuple: vip=192.168.0.10:0, backend=192.168.10.10:0, protocol=0" hv1/ovn-controller.log], [0]) +AT_CHECK([grep -q "Flushing CT for 5-tuple: vip=192.168.0.10:0, backend=192.168.10.30:0, protocol=0" hv1/ovn-controller.log], [0]) + +# Check flush for LB with port and protocol +check ovn-nbctl lb-add lb1 "192.168.30.10:80" "192.168.40.10:8080,192.168.40.20:8090" udp +check ovn-nbctl ls-lb-add sw lb1 +check ovn-nbctl lb-del lb1 +check ovn-nbctl --wait=hv sync + +AT_CHECK([grep -q "Flushing CT for 5-tuple: vip=192.168.30.10:80, backend=192.168.40.10:8080, protocol=17" hv1/ovn-controller.log], [0]) +AT_CHECK([grep -q "Flushing CT for 5-tuple: vip=192.168.30.10:80, backend=192.168.40.20:8090, protocol=17" hv1/ovn-controller.log], [0]) + +# Check recompute when LB is no longer local +check ovn-nbctl lb-add lb1 "192.168.50.10:80" "192.168.60.10:8080" +check ovn-nbctl ls-lb-add sw lb1 +check ovs-vsctl remove interface p1 external_ids iface-id +check ovn-appctl inc-engine/recompute +check ovn-nbctl --wait=hv sync + +AT_CHECK([grep -q "Flushing CT for 5-tuple: vip=192.168.50.10:80, backend=192.168.60.10:8080, protocol=6" hv1/ovn-controller.log], [0]) + +AT_CHECK([test "$(grep -c "Flushing CT for 5-tuple" hv1/ovn-controller.log)" = "6"], [0]) + +OVN_CLEANUP([hv1]) +AT_CLEANUP +]) diff --git a/tests/system-ovn.at b/tests/system-ovn.at index b6be004d2..852a7cee4 100644 --- a/tests/system-ovn.at +++ b/tests/system-ovn.at @@ -10285,3 +10285,193 @@ OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d /connection dropped.*/d"]) AT_CLEANUP ]) + +OVN_FOR_EACH_NORTHD([ +AT_SETUP([load-balancing CT flush backends]) +AT_KEYWORDS([ovnlb]) + +CHECK_CONNTRACK() +CHECK_CONNTRACK_NAT() +ovn_start +OVS_TRAFFIC_VSWITCHD_START() +ADD_BR([br-int]) + +# 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 + +# Start ovn-controller +start_daemon ovn-controller + +# Logical network: +# 2 logical switches "foo" (192.168.1.0/24) and "bar" (172.16.1.0/24) +# connected to a router R1. +# foo has foo1 to act as a client. +# bar has bar1, bar2, bar3 to act as servers. +# +# Loadbalancer VIPs in 30.0.0.0/24 network. + +check ovn-nbctl lr-add R1 +check ovn-nbctl ls-add foo +check ovn-nbctl ls-add bar + +# Connect foo to R1 +check ovn-nbctl lrp-add R1 foo 00:00:01:01:02:03 192.168.1.1/24 +check ovn-nbctl lsp-add foo rp-foo -- set Logical_Switch_Port rp-foo \ + type=router options:router-port=foo addresses=\"00:00:01:01:02:03\" + +# Connect bar to R1 +check ovn-nbctl lrp-add R1 bar 00:00:01:01:02:04 172.16.1.1/24 +check ovn-nbctl lsp-add bar rp-bar -- set Logical_Switch_Port rp-bar \ + type=router options:router-port=bar addresses=\"00:00:01:01:02:04\" + +# Create logical port 'foo1' in switch 'foo'. +ADD_NAMESPACES(foo1) +ADD_VETH(foo1, foo1, br-int, "192.168.1.2/24", "f0:00:00:01:02:03", \ + "192.168.1.1") +check ovn-nbctl lsp-add foo foo1 \ +-- lsp-set-addresses foo1 "f0:00:00:01:02:03 192.168.1.2" + +# Create logical ports 'bar1', 'bar2', 'bar3' in switch 'bar'. +ADD_NAMESPACES(bar1) +ADD_VETH(bar1, bar1, br-int, "172.16.1.2/24", "f0:00:0f:01:02:03", \ + "172.16.1.1") +check ovn-nbctl lsp-add bar bar1 \ +-- lsp-set-addresses bar1 "f0:00:0f:01:02:03 172.16.1.2" + +ADD_NAMESPACES(bar2) +ADD_VETH(bar2, bar2, br-int, "172.16.1.3/24", "f0:00:0f:01:02:04", \ + "172.16.1.1") +check ovn-nbctl lsp-add bar bar2 \ +-- lsp-set-addresses bar2 "f0:00:0f:01:02:04 172.16.1.3" + +ADD_NAMESPACES(bar3) +ADD_VETH(bar3, bar3, br-int, "172.16.1.4/24", "f0:00:0f:01:02:05", \ + "172.16.1.1") +check ovn-nbctl lsp-add bar bar3 \ +-- lsp-set-addresses bar3 "f0:00:0f:01:02:05 172.16.1.4" + +# Config OVN load-balancer with a VIP. +check ovn-nbctl lb-add lb1 30.0.0.1 "172.16.1.2,172.16.1.3,172.16.1.4" +check ovn-nbctl ls-lb-add foo lb1 + +# Create another load-balancer with another VIP. +lb2_uuid=`ovn-nbctl create load_balancer name=lb2 vips:30.0.0.3="172.16.1.2,172.16.1.3,172.16.1.4"` +check ovn-nbctl ls-lb-add foo lb2 + +# Config OVN load-balancer with another VIP (this time with ports). +check ovn-nbctl set load_balancer $lb2_uuid vips:'"30.0.0.2:8000"'='"172.16.1.2:80,172.16.1.3:80,172.16.1.4:80"' + +# Wait for ovn-controller to catch up. +ovn-nbctl --wait=hv sync +OVS_WAIT_UNTIL([ovs-ofctl -O OpenFlow13 dump-groups br-int | \ +grep 'nat(dst=172.16.1.4:80)']) + +# Start webservers in 'bar1', 'bar2' and 'bar3'. +OVS_START_L7([bar1], [http]) +OVS_START_L7([bar2], [http]) +OVS_START_L7([bar3], [http]) + +OVS_WAIT_FOR_OUTPUT([ + for i in `seq 1 20`; do + ip netns exec foo1 wget 30.0.0.1 -t 5 -T 1 --retry-connrefused -v -o wget$i.log; + done + ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +]) + +OVS_WAIT_FOR_OUTPUT([ + for i in `seq 1 20`; do + ip netns exec foo1 wget 30.0.0.2:8000 -t 5 -T 1 --retry-connrefused -v -o wget$i.log; + done + ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +]) + +OVS_WAIT_FOR_OUTPUT([ + for i in `seq 1 20`; do + ip netns exec foo1 wget 30.0.0.3 -t 5 -T 1 --retry-connrefused -v -o wget$i.log; + done + ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +]) + +# Remove one backend +check ovn-nbctl set load_balancer lb1 vips='"30.0.0.1"="172.16.1.2,172.16.1.3"' + +OVS_WAIT_FOR_OUTPUT([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.1,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +]) + +# Remove whole LB +check ovn-nbctl lb-del lb1 + +OVS_WAIT_UNTIL([test "$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.1) | wc -l)" = "0"]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.2,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +]) + +# Remove one VIP +check ovn-nbctl remove load_balancer lb2 vips '"30.0.0.2:8000"' + +OVS_WAIT_UNTIL([test "$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.2) | wc -l)" = "0"]) + +AT_CHECK([ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.2,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.3,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +tcp,orig=(src=192.168.1.2,dst=30.0.0.3,sport=<cleared>,dport=<cleared>),reply=(src=172.16.1.4,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=2,protoinfo=(state=<cleared>) +]) + +# Remove second LB +check ovn-nbctl lb-del lb2 + +OVS_WAIT_UNTIL([test "$(ovs-appctl dpctl/dump-conntrack | FORMAT_CT(30.0.0.3) | wc -l)" = "0"]) + +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([NORTHD_TYPE]) + +as +OVS_TRAFFIC_VSWITCHD_STOP(["/failed to query port patch-.*/d +/connection dropped.*/d"]) +AT_CLEANUP +]) -- 2.39.1 _______________________________________________ dev mailing list [email protected] https://mail.openvswitch.org/mailman/listinfo/ovs-dev
