+}
+
+#define MAX_FLUSHES 3
+
+static void
+acl_ids_handle_rconn_msg(struct ofpbuf *msg, struct tracked_acl_ids
*acl_ids)
+{
+ const struct ofp_header *oh = msg->data;
+
+ enum ofptype type;
+ ofptype_decode(&type, oh);
+
+ if (type == OFPTYPE_ECHO_REQUEST) {
+ rconn_send(swconn, ofputil_encode_echo_reply(oh), NULL);
+ return;
+ }
+
+ struct acl_id *acl_id;
+ if (oh->xid != barrier_xid) {
+ if (type != OFPTYPE_ERROR) {
+ return;
+ }
+ /* Uh oh! It looks like one of the flushes failed :(
+ * Let's find this particular one and move its state
+ * back to SB_DELETED so we can retry the flush. Of
+ * course, if this is a naughty little ID and has
+ * been flushed unsuccessfully too many times, we'll
+ * set it to TO_DELETE so it doesn't cause any more
+ * trouble.
+ */
+ HMAP_FOR_EACH (acl_id, hmap_node, &acl_ids->ids) {
+ if (acl_id->xid != oh->xid) {
+ continue;
+ }
+
+ acl_id->xid = 0;
+ acl_id->flush_count++;
+ if (acl_id->flush_count >= MAX_FLUSHES) {
+ acl_id->state = TO_DELETE;
+ } else {
+ acl_id->state = SB_DELETED;
+ }
+
+ break;
+ }
+ } else {
+ HMAP_FOR_EACH (acl_id, hmap_node, &acl_ids->ids) {
+ if (acl_id->state != FLUSHING) {
+ continue;
+ }
+ acl_id->state = TO_DELETE;
+ }
+ barrier_xid = 0;
+ }
+}
+
+static void
+flush_expired_ids(struct tracked_acl_ids *acl_ids)
+{
+ if (barrier_xid != 0) {
+ /* We haven't received the previous barrier's reply, so
+ * hold off on sending new flushes until we get the
+ * reply.
+ */
+ return;
+ }
+
+ ovs_u128 mask = {
+ /* ct_labels.label BITS[80-95] */
+ .u64.hi = 0xffff0000,
+ };
+ struct acl_id *acl_id;
+ bool send_barrier = false;
+ HMAP_FOR_EACH (acl_id, hmap_node, &acl_ids->ids) {
+ if (acl_id->state != SB_DELETED) {
+ continue;
+ }
+ ovs_u128 ct_id = {
+ .u64.hi = acl_id->id << 16,
+ };
+ VLOG_DBG("Flushing conntrack entry for ACL id %"PRId64,
acl_id->id);
+ struct ofp_ct_match match = {
+ .labels = ct_id,
+ .labels_mask = mask,
+ };
+ struct ofpbuf *msg = ofp_ct_match_encode(&match, NULL,
+
rconn_get_version(swconn));
+ const struct ofp_header *oh = msg->data;
+ acl_id->xid = oh->xid;
+ acl_id->state = FLUSHING;
+ rconn_send(swconn, msg, NULL);
+ send_barrier = true;
+ }
+
+ if (!send_barrier) {
+ return;
+ }
+
+ struct ofpbuf *barrier =
ofputil_encode_barrier_request(OFP15_VERSION);
+ const struct ofp_header *oh = barrier->data;
+ barrier_xid = oh->xid;
+ rconn_send(swconn, barrier, NULL);
+}
+
+static void
+clear_flushed_ids(struct tracked_acl_ids *acl_ids)
+{
+ struct acl_id *acl_id;
+ HMAP_FOR_EACH_SAFE (acl_id, hmap_node, &acl_ids->ids) {
+ if (acl_id->state != TO_DELETE) {
+ continue;
+ }
+ hmap_remove(&acl_ids->ids, &acl_id->hmap_node);
+ acl_id_destroy(acl_id);
+ }
+}
+
+#define MAX_RECV_MSGS 50
+
+void
+acl_ids_run(struct tracked_acl_ids *acl_ids)
+{
+ rconn_run(swconn);
+ if (!rconn_is_connected(swconn)) {
+ rconn_run_wait(swconn);
+ rconn_recv_wait(swconn);
+ return;
+ }
+
+ for (int i = 0; i < MAX_RECV_MSGS; i++) {
+ struct ofpbuf *msg = rconn_recv(swconn);
+ if (!msg) {
+ break;
+ }
+ acl_ids_handle_rconn_msg(msg, acl_ids);
+ ofpbuf_delete(msg);
+ }
+ flush_expired_ids(acl_ids);
+ clear_flushed_ids(acl_ids);
+
+ rconn_run_wait(swconn);
+ rconn_recv_wait(swconn);
+}
diff --git a/controller/acl_ids.h b/controller/acl_ids.h
new file mode 100644
index 000000000..e3556c37e
--- /dev/null
+++ b/controller/acl_ids.h
@@ -0,0 +1,30 @@
+/* Copyright (c) 2024 Red Hat, INc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
<http://www.apache.org/licenses/LICENSE-2.0>
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef OVN_ACL_IDS_H
+#define OVN_ACL_IDS_H
+
+#include <config.h>
+#include "lib/inc-proc-eng.h"
+
+void *en_acl_id_init(struct engine_node *, struct engine_arg *);
+void en_acl_id_run(struct engine_node *, void *);
+void en_acl_id_cleanup(void *);
+
+struct tracked_acl_ids;
+void acl_ids_update_swconn(const char *target, int probe_interval);
+void acl_ids_run(struct tracked_acl_ids *);
+
+#endif /* OVN_ACL_IDS_H */
diff --git a/controller/automake.mk <http://automake.mk>
b/controller/automake.mk <http://automake.mk>
index bb0bf2d33..c19ae27be 100644
--- a/controller/automake.mk <http://automake.mk>
+++ b/controller/automake.mk <http://automake.mk>
@@ -1,5 +1,7 @@
bin_PROGRAMS += controller/ovn-controller
controller_ovn_controller_SOURCES = \
+ controller/acl_ids.c \
+ controller/acl_ids.h \
controller/bfd.c \
controller/bfd.h \
controller/binding.c \
diff --git a/controller/ovn-controller.c b/controller/ovn-controller.c
index 157def2a3..f19c291d6 100644
--- a/controller/ovn-controller.c
+++ b/controller/ovn-controller.c
@@ -88,6 +88,7 @@
#include "lib/dns-resolve.h"
#include "ct-zone.h"
#include "ovn-dns.h"
+#include "acl_ids.h"
VLOG_DEFINE_THIS_MODULE(main);
@@ -864,7 +865,8 @@ ctrl_register_ovs_idl(struct ovsdb_idl *ovs_idl)
SB_NODE(fdb, "fdb") \
SB_NODE(meter, "meter") \
SB_NODE(static_mac_binding, "static_mac_binding") \
- SB_NODE(chassis_template_var, "chassis_template_var")
+ SB_NODE(chassis_template_var, "chassis_template_var") \
+ SB_NODE(acl_id, "acl_id")
enum sb_engine_node {
#define SB_NODE(NAME, NAME_STR) SB_##NAME,
@@ -5095,6 +5097,7 @@ main(int argc, char *argv[])
ENGINE_NODE(mac_cache, "mac_cache");
ENGINE_NODE(bfd_chassis, "bfd_chassis");
ENGINE_NODE(dns_cache, "dns_cache");
+ ENGINE_NODE(acl_id, "acl_id");
#define SB_NODE(NAME, NAME_STR) ENGINE_NODE_SB(NAME, NAME_STR);
SB_NODES
@@ -5303,6 +5306,9 @@ main(int argc, char *argv[])
engine_add_input(&en_controller_output, &en_bfd_chassis,
controller_output_bfd_chassis_handler);
+ engine_add_input(&en_acl_id, &en_sb_acl_id, NULL);
+ engine_add_input(&en_controller_output, &en_acl_id, NULL);
+
struct engine_arg engine_arg = {
.sb_idl = ovnsb_idl_loop.idl,
.ovs_idl = ovs_idl_loop.idl,
@@ -5538,6 +5544,8 @@ main(int argc, char *argv[])
br_int_remote.probe_interval);
pinctrl_update_swconn(br_int_remote.target,
br_int_remote.probe_interval);
+ acl_ids_update_swconn(br_int_remote.target,
+ br_int_remote.probe_interval);
/* Enable ACL matching for double tagged traffic. */
if (ovs_idl_txn && cfg) {
@@ -5842,6 +5850,8 @@ main(int argc, char *argv[])
!ovnsb_idl_txn, !ovs_idl_txn);
stopwatch_stop(IF_STATUS_MGR_RUN_STOPWATCH_NAME,
time_msec());
+
+ acl_ids_run(engine_get_data(&en_acl_id));
}
}
diff --git a/lib/logical-fields.c b/lib/logical-fields.c
index 5b578b5c2..89431b939 100644
--- a/lib/logical-fields.c
+++ b/lib/logical-fields.c
@@ -192,6 +192,8 @@ ovn_init_symtab(struct shash *symtab)
"ct_label[96..127]",
WR_CT_COMMIT);
expr_symtab_add_subfield_scoped(symtab, "ct_label.obs_unused",
NULL,
"ct_label[0..95]", WR_CT_COMMIT);
+ expr_symtab_add_subfield_scoped(symtab, "ct_label.acl_id", NULL,
+ "ct_label[80..95]", WR_CT_COMMIT);
expr_symtab_add_field(symtab, "ct_state", MFF_CT_STATE, NULL,
false);
diff --git a/northd/en-acl-ids.c b/northd/en-acl-ids.c
index 897cc2da1..cb220dd80 100644
--- a/northd/en-acl-ids.c
+++ b/northd/en-acl-ids.c
@@ -204,3 +204,16 @@ void sync_acl_ids(const struct acl_id_data
*id_data,
}
}
}
+
+int64_t
+get_acl_id(const struct acl_id_data *acl_id_data, const struct
nbrec_acl *acl)
+{
+ struct acl_id *acl_id;
+ uint32_t hash = uuid_hash(&acl->header_.uuid);
+ HMAP_FOR_EACH_WITH_HASH (acl_id, node, hash, &acl_id_data->ids) {
+ if (uuid_equals(&acl_id->nb_acl_uuid, &acl->header_.uuid)) {
+ return acl_id->id;
+ }
+ }
+ return 0;
+}
As mentioned on the previous patch, if we do the UUID 1:1 mapping this
search becomes redundant.
diff --git a/northd/en-acl-ids.h b/northd/en-acl-ids.h
index 8b60b3c7c..8bea2e078 100644
--- a/northd/en-acl-ids.h
+++ b/northd/en-acl-ids.h
@@ -14,4 +14,7 @@ void en_acl_id_cleanup(void *data);
struct acl_id_data;
void sync_acl_ids(const struct acl_id_data *, struct ovsdb_idl_txn *,
struct ovsdb_idl_index *sbrec_acl_id_by_id);
+
+struct nbrec_acl;
+int64_t get_acl_id(const struct acl_id_data *, const struct
nbrec_acl *);
#endif
diff --git a/northd/en-lflow.c b/northd/en-lflow.c
index fa1f0236d..3d57a469b 100644
--- a/northd/en-lflow.c
+++ b/northd/en-lflow.c
@@ -96,6 +96,7 @@ lflow_get_input_data(struct engine_node *node,
struct ed_type_sampling_app_data *sampling_app_data =
engine_get_input_data("sampling_app", node);
lflow_input->sampling_apps = &sampling_app_data->apps;
+ lflow_input->acl_id_data = engine_get_input_data("acl_id", node);
}
void en_lflow_run(struct engine_node *node, void *data)
diff --git a/northd/inc-proc-northd.c b/northd/inc-proc-northd.c
index 43abf042d..04c208c97 100644
--- a/northd/inc-proc-northd.c
+++ b/northd/inc-proc-northd.c
@@ -293,6 +293,7 @@ void inc_proc_northd_init(struct ovsdb_idl_loop *nb,
engine_add_input(&en_lflow, &en_port_group,
lflow_port_group_handler);
engine_add_input(&en_lflow, &en_lr_stateful,
lflow_lr_stateful_handler);
engine_add_input(&en_lflow, &en_ls_stateful,
lflow_ls_stateful_handler);
+ engine_add_input(&en_lflow, &en_acl_id, NULL);
engine_add_input(&en_sync_to_sb_addr_set, &en_northd, NULL);
engine_add_input(&en_sync_to_sb_addr_set, &en_lr_stateful, NULL);
diff --git a/northd/northd.c b/northd/northd.c
index 8dab88f62..081305b09 100644
--- a/northd/northd.c
+++ b/northd/northd.c
@@ -206,6 +206,9 @@ BUILD_ASSERT_DECL(ACL_OBS_STAGE_MAX < (1 << 2));
#define REG_OBS_COLLECTOR_ID_NEW "reg8[0..7]"
#define REG_OBS_COLLECTOR_ID_EST "reg8[8..15]"
+/* Register used for storing persistent ACL IDs */
+#define REG_ACL_ID "reg7[0..15]"
+
/* Register used for temporarily store ECMP eth.src to avoid
masked ct_label
* access. It doesn't really occupy registers because the content
of the
* register is saved to stack and then restored in the same flow.
@@ -7063,7 +7066,8 @@ consider_acl(struct lflow_table *lflows, const
struct ovn_datapath *od,
const struct nbrec_acl *acl, bool has_stateful,
const struct shash *meter_groups, uint64_t max_acl_tier,
struct ds *match, struct ds *actions,
- struct lflow_ref *lflow_ref)
+ struct lflow_ref *lflow_ref,
+ const struct acl_id_data *acl_id_data)
{
bool ingress = !strcmp(acl->direction, "from-lport") ? true
:false;
enum ovn_stage stage;
@@ -7151,8 +7155,17 @@ consider_acl(struct lflow_table *lflows,
const struct ovn_datapath *od,
ds_put_cstr(actions, REGBIT_CONNTRACK_COMMIT" = 1; ");
if (!strcmp(acl->action, "allow-established")) {
- ds_put_format(actions,
- REGBIT_ACL_PERSIST_ID " = 1; ");
+ int64_t id = get_acl_id(acl_id_data, acl);
+ if (id) {
+ ds_put_format(actions,
+ REG_ACL_ID " = %"PRId64 "; "
+ REGBIT_ACL_PERSIST_ID " = 1; ",
+ id);
+ } else {
+ static struct vlog_rate_limit rl =
VLOG_RATE_LIMIT_INIT(1, 1);
+ VLOG_WARN_RL(&rl, "No ID found for ACL "UUID_FMT"
(%s)",
+ UUID_ARGS(&acl->header_.uuid),
acl->match);
+ }
}
/* For stateful ACLs sample "new" and "established"
packets. */
@@ -7476,7 +7489,8 @@ build_acls(const struct ls_stateful_record
*ls_stateful_rec,
const struct shash *meter_groups,
const struct sampling_app_table *sampling_apps,
const struct chassis_features *features,
- struct lflow_ref *lflow_ref)
+ struct lflow_ref *lflow_ref,
+ const struct acl_id_data *acl_id_data)
{
const char *default_acl_action = default_acl_drop
? debug_implicit_drop_action()
@@ -7686,7 +7700,8 @@ build_acls(const struct ls_stateful_record
*ls_stateful_rec,
lflow_ref);
consider_acl(lflows, od, acl, has_stateful,
meter_groups, ls_stateful_rec->max_acl_tier,
- &match, &actions, lflow_ref);
+ &match, &actions, lflow_ref,
+ acl_id_data);
build_acl_sample_flows(ls_stateful_rec, od, lflows, acl,
&match, &actions, sampling_apps,
features, lflow_ref);
@@ -7705,7 +7720,8 @@ build_acls(const struct ls_stateful_record
*ls_stateful_rec,
lflow_ref);
consider_acl(lflows, od, acl, has_stateful,
meter_groups,
ls_stateful_rec->max_acl_tier,
- &match, &actions, lflow_ref);
+ &match, &actions, lflow_ref,
+ acl_id_data);
build_acl_sample_flows(ls_stateful_rec, od,
lflows, acl,
&match, &actions,
sampling_apps,
features, lflow_ref);
@@ -8394,6 +8410,7 @@ build_stateful(struct ovn_datapath *od, struct
lflow_table *lflows,
"ct_mark.obs_stage = " REGBIT_ACL_OBS_STAGE "; "
"ct_mark.obs_collector_id = "
REG_OBS_COLLECTOR_ID_EST "; "
"ct_label.obs_point_id = "
REG_OBS_POINT_ID_EST "; "
+ "ct_label.acl_id = " REG_ACL_ID "; "
"}; next;");
ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 100,
REGBIT_CONNTRACK_COMMIT" == 1 && "
@@ -8415,6 +8432,7 @@ build_stateful(struct ovn_datapath *od, struct
lflow_table *lflows,
"ct_commit { "
"ct_mark.blocked = 0; "
"ct_mark.allow_established = "
REGBIT_ACL_PERSIST_ID "; "
+ "ct_label.acl_id = " REG_ACL_ID "; "
"}; next;");
ovn_lflow_add(lflows, od, S_SWITCH_IN_STATEFUL, 100,
REGBIT_CONNTRACK_COMMIT" == 1 && "
@@ -17216,7 +17234,8 @@ build_ls_stateful_flows(const struct
ls_stateful_record *ls_stateful_rec,
const struct shash *meter_groups,
const struct sampling_app_table
*sampling_apps,
const struct chassis_features *features,
- struct lflow_table *lflows)
+ struct lflow_table *lflows,
+ const struct acl_id_data *acl_id_data)
{
build_ls_stateful_rec_pre_acls(ls_stateful_rec, od, ls_pgs,
lflows,
ls_stateful_rec->lflow_ref);
@@ -17225,7 +17244,8 @@ build_ls_stateful_flows(const struct
ls_stateful_record *ls_stateful_rec,
build_acl_hints(ls_stateful_rec, od, lflows,
ls_stateful_rec->lflow_ref);
build_acls(ls_stateful_rec, od, lflows, ls_pgs, meter_groups,
- sampling_apps, features, ls_stateful_rec->lflow_ref);
+ sampling_apps, features, ls_stateful_rec->lflow_ref,
+ acl_id_data);
build_lb_hairpin(ls_stateful_rec, od, lflows,
ls_stateful_rec->lflow_ref);
}
@@ -17253,6 +17273,7 @@ struct lswitch_flow_build_info {
struct hmap *parsed_routes;
struct hmap *route_policies;
struct simap *route_tables;
+ const struct acl_id_data *acl_id_data;
};
/* Helper function to combine all lflow generation which is
iterated by
@@ -17552,7 +17573,8 @@ build_lflows_thread(void *arg)
lsi->meter_groups,
lsi->sampling_apps,
lsi->features,
- lsi->lflows);
+ lsi->lflows,
+ lsi->acl_id_data);
}
}
@@ -17629,7 +17651,8 @@ build_lswitch_and_lrouter_flows(
const struct sampling_app_table *sampling_apps,
struct hmap *parsed_routes,
struct hmap *route_policies,
- struct simap *route_tables)
+ struct simap *route_tables,
+ const struct acl_id_data *acl_id_data)
{
char *svc_check_match = xasprintf("eth.dst == %s",
svc_monitor_mac);
@@ -17667,6 +17690,7 @@ build_lswitch_and_lrouter_flows(
lsiv[index].parsed_routes = parsed_routes;
lsiv[index].route_tables = route_tables;
lsiv[index].route_policies = route_policies;
+ lsiv[index].acl_id_data = acl_id_data;
ds_init(&lsiv[index].match);
ds_init(&lsiv[index].actions);
@@ -17713,6 +17737,7 @@ build_lswitch_and_lrouter_flows(
.route_policies = route_policies,
.match = DS_EMPTY_INITIALIZER,
.actions = DS_EMPTY_INITIALIZER,
+ .acl_id_data = acl_id_data,
};
/* Combined build - all lflow generation from lswitch and
lrouter
@@ -17786,7 +17811,8 @@ build_lswitch_and_lrouter_flows(
lsi.meter_groups,
lsi.sampling_apps,
lsi.features,
- lsi.lflows);
+ lsi.lflows,
+ lsi.acl_id_data);
}
stopwatch_stop(LFLOWS_LS_STATEFUL_STOPWATCH_NAME,
time_msec());
stopwatch_start(LFLOWS_IGMP_STOPWATCH_NAME, time_msec());
@@ -17879,7 +17905,8 @@ void build_lflows(struct ovsdb_idl_txn
*ovnsb_txn,
input_data->sampling_apps,
input_data->parsed_routes,
input_data->route_policies,
- input_data->route_tables);
+ input_data->route_tables,
+ input_data->acl_id_data);
if (parallelization_state == STATE_INIT_HASH_SIZES) {
parallelization_state = STATE_USE_PARALLELIZATION;
@@ -18306,7 +18333,8 @@ lflow_handle_ls_stateful_changes(struct
ovsdb_idl_txn *ovnsb_txn,
lflow_input->meter_groups,
lflow_input->sampling_apps,
lflow_input->features,
- lflows);
+ lflows,
+ lflow_input->acl_id_data);
/* Sync the new flows to SB. */
bool handled = lflow_ref_sync_lflows(
diff --git a/northd/northd.h b/northd/northd.h
index bccb1c5d8..175c318af 100644
--- a/northd/northd.h
+++ b/northd/northd.h
@@ -232,6 +232,7 @@ struct lflow_input {
struct hmap *parsed_routes;
struct hmap *route_policies;
struct simap *route_tables;
+ const struct acl_id_data *acl_id_data;
};
extern int parallelization_state;
diff --git a/tests/ovn-northd.at <http://ovn-northd.at>
b/tests/ovn-northd.at <http://ovn-northd.at>
index 1d90622e1..b5b94330b 100644
--- a/tests/ovn-northd.at <http://ovn-northd.at>
+++ b/tests/ovn-northd.at <http://ovn-northd.at>
@@ -14297,21 +14297,27 @@ after_lb_uuid=$(fetch_column nb:ACL _uuid
priority=1003)
check ovn-nbctl set acl $ingress_uuid action=allow-established
check ovn-nbctl set acl $egress_uuid action=allow-established
-check ovn-nbctl set acl $after_lb_uuid action=allow-established
+check ovn-nbctl --wait=sb set acl $after_lb_uuid
action=allow-established
+
+dnl Retrieve the IDs for the ACLs so we can check them properly.
+
+ingress_id=$(fetch_column ACL_ID id nb_acl=$ingress_uuid)
+egress_id=$(fetch_column ACL_ID id nb_acl=$egress_uuid)
+after_lb_id=$(fetch_column ACL_ID id nb_acl=$after_lb_uuid)
dnl Now we should see the registers being set to the appropriate
values.
-AT_CHECK([ovn-sbctl lflow-list sw | grep ls_in_acl_eval | grep
priority=2001 | ovn_strip_lflows], [0], [dnl
- table=??(ls_in_acl_eval ), priority=2001 , match=(reg0[[7]]
== 1 && (tcp)), action=(reg8[[16]] = 1; reg0[[1]] = 1; reg0[[20]] =
1; next;)
+AT_CHECK_UNQUOTED([ovn-sbctl lflow-list sw | grep ls_in_acl_eval |
grep priority=2001 | ovn_strip_lflows], [0], [dnl
+ table=??(ls_in_acl_eval ), priority=2001 , match=(reg0[[7]]
== 1 && (tcp)), action=(reg8[[16]] = 1; reg0[[1]] = 1; reg7[[0..15]]
= $ingress_id; reg0[[20]] = 1; next;)
table=??(ls_in_acl_eval ), priority=2001 , match=(reg0[[8]]
== 1 && (tcp)), action=(reg8[[16]] = 1; next;)
])
-AT_CHECK([ovn-sbctl lflow-list sw | grep ls_in_acl_after_lb_eval |
grep priority=2003 | ovn_strip_lflows], [0], [dnl
- table=??(ls_in_acl_after_lb_eval), priority=2003 ,
match=(reg0[[7]] == 1 && (udp)), action=(reg8[[16]] = 1; reg0[[1]] =
1; reg0[[20]] = 1; next;)
+AT_CHECK_UNQUOTED([ovn-sbctl lflow-list sw | grep
ls_in_acl_after_lb_eval | grep priority=2003 | ovn_strip_lflows],
[0], [dnl
+ table=??(ls_in_acl_after_lb_eval), priority=2003 ,
match=(reg0[[7]] == 1 && (udp)), action=(reg8[[16]] = 1; reg0[[1]] =
1; reg7[[0..15]] = $after_lb_id; reg0[[20]] = 1; next;)
table=??(ls_in_acl_after_lb_eval), priority=2003 ,
match=(reg0[[8]] == 1 && (udp)), action=(reg8[[16]] = 1; next;)
])
-AT_CHECK([ovn-sbctl lflow-list sw | grep ls_out_acl_eval | grep
priority=2002 | ovn_strip_lflows], [0], [dnl
- table=??(ls_out_acl_eval ), priority=2002 , match=(reg0[[7]]
== 1 && (ip)), action=(reg8[[16]] = 1; reg0[[1]] = 1; reg0[[20]] =
1; next;)
+AT_CHECK_UNQUOTED([ovn-sbctl lflow-list sw | grep ls_out_acl_eval |
grep priority=2002 | ovn_strip_lflows], [0], [dnl
+ table=??(ls_out_acl_eval ), priority=2002 , match=(reg0[[7]]
== 1 && (ip)), action=(reg8[[16]] = 1; reg0[[1]] = 1; reg7[[0..15]]
= $egress_id; reg0[[20]] = 1; next;)
table=??(ls_out_acl_eval ), priority=2002 , match=(reg0[[8]]
== 1 && (ip)), action=(reg8[[16]] = 1; next;)
])
We should also check that the flow indeed commits the ID into ct_label.
diff --git a/tests/system-ovn.at <http://system-ovn.at>
b/tests/system-ovn.at <http://system-ovn.at>
index a6ddda0f7..27e112a26 100644
--- a/tests/system-ovn.at <http://system-ovn.at>
+++ b/tests/system-ovn.at <http://system-ovn.at>
@@ -14251,6 +14251,18 @@ test
: > output.txt
+# Get the ID for this ACL
+acl_id=$(fetch_column ACL_ID id nb_acl=$acl_uuid)
+acl_id=$(printf %x $acl_id)
+
+OVS_WAIT_FOR_OUTPUT([ovs-appctl dpctl/dump-conntrack |
FORMAT_CT(192.168.1.2) | \
+grep "labels=0x"$acl_id"00000000000000000000" | \
+sed -e 's/zone=[[0-9]]*/zone=<cleared>/' | \
+sed -e 's/mark=[[0-9]]*/mark=<cleared>/' | \
+sed -e 's/labels=0x[[0-9a-f]]*/labels=<cleared>/'], [0], [dnl
+tcp,orig=(src=192.168.1.1,dst=192.168.1.2,sport=<cleared>,dport=<cleared>),reply=(src=192.168.1.2,dst=192.168.1.1,sport=<cleared>,dport=<cleared>),zone=<cleared>,mark=<cleared>,labels=<cleared>,protoinfo=(state=<cleared>)
+])
+
# Adjust the ACL so that it no longer matches
check ovn-nbctl set ACL $acl_uuid match="\"ip4.dst == 192.168.1.3\""
@@ -14264,6 +14276,14 @@ test
: > output.txt
+# Now remove the ACL. This should remove the conntrack entry as well.
+check ovn-nbctl --wait=hv acl-del sw from-lport 1000 'ip4.dst ==
192.168.1.3'
+
+OVS_WAIT_FOR_OUTPUT([ovs-appctl dpctl/dump-conntrack |
FORMAT_CT(192.168.1.2) | \
+grep "labels=0x"$acl_id"00000000000000000000" | \
+sed -e 's/zone=[[0-9]]*/zone=<cleared>/'], [0], [dnl
+])
+
OVS_APP_EXIT_AND_WAIT([ovn-controller])
as ovn-sb
--
2.45.2
_______________________________________________
dev mailing list
[email protected] <mailto:[email protected]>
https://mail.openvswitch.org/mailman/listinfo/ovs-dev
<https://mail.openvswitch.org/mailman/listinfo/ovs-dev>
Thanks,
Ales