[ovs-dev] [RFC ovn 1/5] ovn-controller: Add support for Logical_Flow control meters
Lorenzo Bianconi
lorenzo.bianconi at redhat.com
Sat Apr 24 10:39:31 UTC 2021
From: Dumitru Ceara <dceara at redhat.com>
Add a new 'controller_meter' column to OVN Southbound Logical_Flow
table. This stores an optional string which should correspond to
the Meter that must be used for rate limiting controller actions
generated by packets hitting the flow.
Add a new 'ofctrl_add_flow_meter' function to create a new 'ovn_flow'
with an attached controller meter.
Change ofctrl_check_and_add_flow to allow specifying a meter ID for
packets that are punted to controller.
Change consider_logical_flow to parse controller_meter from the logical
flow and use it when building openflow entries.
Add a new 'ctrl_meter_id' field to 'struct ovnact_encode_params' to be
used when encoding controller actions from logical flow actions.
Co-authored-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi at redhat.com>
Signed-off-by: Dumitru Ceara <dceara at redhat.com>
---
controller/lflow.c | 38 ++++++++++++++++++++++---
controller/ofctrl.c | 36 +++++++++++++++++------
controller/ofctrl.h | 13 +++++++--
controller/physical.c | 3 +-
include/ovn/actions.h | 2 ++
lib/actions.c | 66 +++++++++++++++++++++++--------------------
ovn-sb.ovsschema | 6 ++--
ovn-sb.xml | 6 ++++
8 files changed, 121 insertions(+), 49 deletions(-)
diff --git a/controller/lflow.c b/controller/lflow.c
index 680b8cca1..684fc43e6 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -557,6 +557,26 @@ update_conj_id_ofs(uint32_t *conj_id_ofs, uint32_t n_conjs)
return false;
}
+static void
+lflow_parse_ctrl_meter(const struct sbrec_logical_flow *lflow,
+ struct ovn_extend_table *meter_table,
+ uint32_t *meter_id)
+{
+ *meter_id = NX_CTLR_NO_METER;
+
+ if (lflow->controller_meter) {
+ *meter_id = ovn_extend_table_assign_id(meter_table,
+ lflow->controller_meter,
+ lflow->header_.uuid);
+ if (*meter_id == EXT_TABLE_ID_INVALID) {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
+ VLOG_WARN_RL(&rl, "Unable to assign id for meter: %s",
+ lflow->controller_meter);
+ return;
+ }
+ }
+}
+
static void
add_matches_to_flow_table(const struct sbrec_logical_flow *lflow,
const struct sbrec_datapath_binding *dp,
@@ -572,6 +592,13 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow,
.dp = dp,
};
+ /* Parse any meter to be used if this flow should punt packets to
+ * controller.
+ */
+ uint32_t ctrl_meter_id = NX_CTLR_NO_METER;
+ lflow_parse_ctrl_meter(lflow, l_ctx_out->meter_table,
+ &ctrl_meter_id);
+
/* Encode OVN logical actions into OpenFlow. */
uint64_t ofpacts_stub[1024 / 8];
struct ofpbuf ofpacts = OFPBUF_STUB_INITIALIZER(ofpacts_stub);
@@ -595,6 +622,7 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow,
.ct_snat_vip_ptable = OFTABLE_CT_SNAT_FOR_VIP,
.fdb_ptable = OFTABLE_GET_FDB,
.fdb_lookup_ptable = OFTABLE_LOOKUP_FDB,
+ .ctrl_meter_id = ctrl_meter_id,
};
ovnacts_encode(ovnacts->data, ovnacts->size, &ep, &ofpacts);
@@ -621,9 +649,10 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow,
}
}
if (!m->n) {
- ofctrl_add_flow(l_ctx_out->flow_table, ptable, lflow->priority,
- lflow->header_.uuid.parts[0], &m->match, &ofpacts,
- &lflow->header_.uuid);
+ ofctrl_add_flow_meter(l_ctx_out->flow_table, ptable, lflow->priority,
+ lflow->header_.uuid.parts[0], &m->match,
+ &ofpacts, &lflow->header_.uuid,
+ ctrl_meter_id);
} else {
uint64_t conj_stubs[64 / 8];
struct ofpbuf conj;
@@ -641,7 +670,8 @@ add_matches_to_flow_table(const struct sbrec_logical_flow *lflow,
ofctrl_add_or_append_flow(l_ctx_out->flow_table, ptable,
lflow->priority, 0,
- &m->match, &conj, &lflow->header_.uuid);
+ &m->match, &conj, &lflow->header_.uuid,
+ ctrl_meter_id);
ofpbuf_uninit(&conj);
}
}
diff --git a/controller/ofctrl.c b/controller/ofctrl.c
index c29c3d180..126df7741 100644
--- a/controller/ofctrl.c
+++ b/controller/ofctrl.c
@@ -66,6 +66,7 @@ struct ovn_flow {
struct ofpact *ofpacts;
size_t ofpacts_len;
uint64_t cookie;
+ uint32_t ctrl_meter_id; /* Meter to be used for controller actions. */
};
/* A desired flow, in struct ovn_desired_flow_table, calculated by the
@@ -220,7 +221,8 @@ static struct desired_flow *desired_flow_alloc(
uint16_t priority,
uint64_t cookie,
const struct match *match,
- const struct ofpbuf *actions);
+ const struct ofpbuf *actions,
+ uint32_t meter_id);
static struct desired_flow *desired_flow_lookup(
struct ovn_desired_flow_table *,
const struct ovn_flow *target);
@@ -1025,10 +1027,10 @@ ofctrl_check_and_add_flow(struct ovn_desired_flow_table *flow_table,
uint64_t cookie, const struct match *match,
const struct ofpbuf *actions,
const struct uuid *sb_uuid,
- bool log_duplicate_flow)
+ uint32_t meter_id, bool log_duplicate_flow)
{
struct desired_flow *f = desired_flow_alloc(table_id, priority, cookie,
- match, actions);
+ match, actions, meter_id);
if (desired_flow_lookup_check_uuid(flow_table, &f->flow, sb_uuid)) {
if (log_duplicate_flow) {
@@ -1055,9 +1057,19 @@ ofctrl_add_flow(struct ovn_desired_flow_table *desired_flows,
uint8_t table_id, uint16_t priority, uint64_t cookie,
const struct match *match, const struct ofpbuf *actions,
const struct uuid *sb_uuid)
+{
+ ofctrl_add_flow_meter(desired_flows, table_id, priority, cookie,
+ match, actions, sb_uuid, NX_CTLR_NO_METER);
+}
+
+void
+ofctrl_add_flow_meter(struct ovn_desired_flow_table *desired_flows,
+ uint8_t table_id, uint16_t priority, uint64_t cookie,
+ const struct match *match, const struct ofpbuf *actions,
+ const struct uuid *sb_uuid, uint32_t meter_id)
{
ofctrl_check_and_add_flow(desired_flows, table_id, priority, cookie,
- match, actions, sb_uuid, true);
+ match, actions, sb_uuid, meter_id, true);
}
/* Either add a new flow, or append actions on an existing flow. If the
@@ -1068,12 +1080,14 @@ ofctrl_add_or_append_flow(struct ovn_desired_flow_table *desired_flows,
uint8_t table_id, uint16_t priority, uint64_t cookie,
const struct match *match,
const struct ofpbuf *actions,
- const struct uuid *sb_uuid)
+ const struct uuid *sb_uuid,
+ uint32_t meter_id)
{
struct desired_flow *existing;
struct desired_flow *f;
- f = desired_flow_alloc(table_id, priority, cookie, match, actions);
+ f = desired_flow_alloc(table_id, priority, cookie, match, actions,
+ meter_id);
existing = desired_flow_lookup_conjunctive(desired_flows, &f->flow);
if (existing) {
/* There's already a flow with this particular match and action
@@ -1278,7 +1292,7 @@ ofctrl_flood_remove_flows(struct ovn_desired_flow_table *flow_table,
static void
ovn_flow_init(struct ovn_flow *f, uint8_t table_id, uint16_t priority,
uint64_t cookie, const struct match *match,
- const struct ofpbuf *actions)
+ const struct ofpbuf *actions, uint32_t meter_id)
{
f->table_id = table_id;
f->priority = priority;
@@ -1287,11 +1301,13 @@ ovn_flow_init(struct ovn_flow *f, uint8_t table_id, uint16_t priority,
f->ofpacts_len = actions->size;
f->hash = ovn_flow_match_hash(f);
f->cookie = cookie;
+ f->ctrl_meter_id = meter_id;
}
static struct desired_flow *
desired_flow_alloc(uint8_t table_id, uint16_t priority, uint64_t cookie,
- const struct match *match, const struct ofpbuf *actions)
+ const struct match *match, const struct ofpbuf *actions,
+ uint32_t meter_id)
{
struct desired_flow *f = xmalloc(sizeof *f);
ovs_list_init(&f->references);
@@ -1300,7 +1316,7 @@ desired_flow_alloc(uint8_t table_id, uint16_t priority, uint64_t cookie,
ovs_list_init(&f->track_list_node);
f->installed_flow = NULL;
f->is_deleted = false;
- ovn_flow_init(&f->flow, table_id, priority, cookie, match, actions);
+ ovn_flow_init(&f->flow, table_id, priority, cookie, match, actions, meter_id);
return f;
}
@@ -1326,6 +1342,7 @@ installed_flow_dup(struct desired_flow *src)
dst->flow.ofpacts_len = src->flow.ofpacts_len;
dst->flow.hash = src->flow.hash;
dst->flow.cookie = src->flow.cookie;
+ dst->flow.ctrl_meter_id = src->flow.ctrl_meter_id;
return dst;
}
@@ -1352,6 +1369,7 @@ desired_flow_lookup__(struct ovn_desired_flow_table *flow_table,
struct ovn_flow *f = &d->flow;
if (f->table_id == target->table_id
&& f->priority == target->priority
+ && f->ctrl_meter_id == target->ctrl_meter_id
&& minimatch_equal(&f->match, &target->match)) {
if (!match_cb || match_cb(d, arg)) {
diff --git a/controller/ofctrl.h b/controller/ofctrl.h
index 88769566a..db374d4e8 100644
--- a/controller/ofctrl.h
+++ b/controller/ofctrl.h
@@ -78,7 +78,15 @@ void ofctrl_add_or_append_flow(struct ovn_desired_flow_table *desired_flows,
uint8_t table_id, uint16_t priority,
uint64_t cookie, const struct match *match,
const struct ofpbuf *actions,
- const struct uuid *sb_uuid);
+ const struct uuid *sb_uuid,
+ uint32_t meter_id);
+
+void ofctrl_add_flow_meter(struct ovn_desired_flow_table *desired_flows,
+ uint8_t table_id, uint16_t priority,
+ uint64_t cookie, const struct match *match,
+ const struct ofpbuf *actions,
+ const struct uuid *sb_uuid,
+ uint32_t meter_id);
/* Removes a bundles of flows from the flow table for a specific sb_uuid. The
* flows are removed only if they are not referenced by any other sb_uuid(s).
@@ -112,7 +120,8 @@ void ofctrl_check_and_add_flow(struct ovn_desired_flow_table *,
uint8_t table_id, uint16_t priority,
uint64_t cookie, const struct match *,
const struct ofpbuf *ofpacts,
- const struct uuid *, bool log_duplicate_flow);
+ const struct uuid *, uint32_t meter_id,
+ bool log_duplicate_flow);
bool ofctrl_is_connected(void);
diff --git a/controller/physical.c b/controller/physical.c
index 96c959d18..95f92a85e 100644
--- a/controller/physical.c
+++ b/controller/physical.c
@@ -858,7 +858,8 @@ put_local_common_flows(uint32_t dp_key, uint32_t port_key,
put_resubmit(OFTABLE_LOG_TO_PHY, ofpacts_p);
put_stack(MFF_IN_PORT, ofpact_put_STACK_POP(ofpacts_p));
ofctrl_check_and_add_flow(flow_table, OFTABLE_SAVE_INPORT, 100, 0,
- &match, ofpacts_p, hc_uuid, false);
+ &match, ofpacts_p, hc_uuid, NX_CTLR_NO_METER,
+ false);
}
}
diff --git a/include/ovn/actions.h b/include/ovn/actions.h
index 040213177..ab03df12c 100644
--- a/include/ovn/actions.h
+++ b/include/ovn/actions.h
@@ -795,6 +795,8 @@ struct ovnact_encode_params {
* 'get_fdb' to resubmit. */
uint8_t fdb_lookup_ptable; /* OpenFlow table for
* 'lookup_fdb' to resubmit. */
+ uint32_t ctrl_meter_id; /* Meter to be used if the resulting flow
+ sends packets to controller. */
};
void ovnacts_encode(const struct ovnact[], size_t ovnacts_len,
diff --git a/lib/actions.c b/lib/actions.c
index b3433f49e..155b4a45a 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -105,10 +105,10 @@ encode_finish_controller_op(size_t ofs, struct ofpbuf *ofpacts)
}
static void
-encode_controller_op(enum action_opcode opcode, struct ofpbuf *ofpacts)
+encode_controller_op(enum action_opcode opcode, uint32_t meter_id,
+ struct ofpbuf *ofpacts)
{
- size_t ofs = encode_start_controller_op(opcode, false, NX_CTLR_NO_METER,
- ofpacts);
+ size_t ofs = encode_start_controller_op(opcode, false, meter_id, ofpacts);
encode_finish_controller_op(ofs, ofpacts);
}
@@ -1647,7 +1647,7 @@ encode_nested_actions(const struct ovnact_nest *on,
* 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,
- NX_CTLR_NO_METER, ofpacts);
+ ep->ctrl_meter_id, ofpacts);
ofpacts_put_openflow_actions(inner_ofpacts.data, inner_ofpacts.size,
ofpacts, OFP15_VERSION);
encode_finish_controller_op(oc_offset, ofpacts);
@@ -1698,10 +1698,10 @@ encode_ICMP6_ERROR(const struct ovnact_nest *on,
static void
encode_IGMP(const struct ovnact_null *a OVS_UNUSED,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
- encode_controller_op(ACTION_OPCODE_IGMP, ofpacts);
+ encode_controller_op(ACTION_OPCODE_IGMP, ep->ctrl_meter_id, ofpacts);
}
static void
@@ -1943,6 +1943,7 @@ format_PUT_ND(const struct ovnact_put_mac_bind *put_mac, struct ds *s)
static void
encode_put_mac(const struct ovnact_put_mac_bind *put_mac,
+ const struct ovnact_encode_params *ep,
enum mf_field_id ip_field, enum action_opcode opcode,
struct ofpbuf *ofpacts)
{
@@ -1952,24 +1953,24 @@ encode_put_mac(const struct ovnact_put_mac_bind *put_mac,
{ expr_resolve_field(&put_mac->mac), MFF_ETH_SRC }
};
encode_setup_args(args, ARRAY_SIZE(args), ofpacts);
- encode_controller_op(opcode, ofpacts);
+ encode_controller_op(opcode, ep->ctrl_meter_id, ofpacts);
encode_restore_args(args, ARRAY_SIZE(args), ofpacts);
}
static void
encode_PUT_ARP(const struct ovnact_put_mac_bind *put_mac,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
- encode_put_mac(put_mac, MFF_REG0, ACTION_OPCODE_PUT_ARP, ofpacts);
+ encode_put_mac(put_mac, ep, MFF_REG0, ACTION_OPCODE_PUT_ARP, ofpacts);
}
static void
encode_PUT_ND(const struct ovnact_put_mac_bind *put_mac,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
- encode_put_mac(put_mac, MFF_XXREG0, ACTION_OPCODE_PUT_ND, ofpacts);
+ encode_put_mac(put_mac, ep, MFF_XXREG0, ACTION_OPCODE_PUT_ND, ofpacts);
}
static void
@@ -2670,13 +2671,13 @@ encode_put_dhcpv6_option(const struct ovnact_gen_option *o,
static void
encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
struct mf_subfield dst = expr_resolve_field(&pdo->dst);
size_t oc_offset = encode_start_controller_op(ACTION_OPCODE_PUT_DHCP_OPTS,
- true, NX_CTLR_NO_METER,
+ true, ep->ctrl_meter_id,
ofpacts);
nx_put_header(ofpacts, dst.field->id, OFP15_VERSION, false);
ovs_be32 ofs = htonl(dst.ofs);
@@ -2723,13 +2724,13 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo,
static void
encode_PUT_DHCPV6_OPTS(const struct ovnact_put_opts *pdo,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
struct mf_subfield dst = expr_resolve_field(&pdo->dst);
size_t oc_offset = encode_start_controller_op(
- ACTION_OPCODE_PUT_DHCPV6_OPTS, true, NX_CTLR_NO_METER, ofpacts);
+ ACTION_OPCODE_PUT_DHCPV6_OPTS, true, ep->ctrl_meter_id, ofpacts);
nx_put_header(ofpacts, dst.field->id, OFP15_VERSION, false);
ovs_be32 ofs = htonl(dst.ofs);
ofpbuf_put(ofpacts, &ofs, sizeof ofs);
@@ -2756,10 +2757,11 @@ format_DHCP6_REPLY(const struct ovnact_null *a OVS_UNUSED, struct ds *s)
static void
encode_DHCP6_REPLY(const struct ovnact_null *a OVS_UNUSED,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
- encode_controller_op(ACTION_OPCODE_DHCP6_SERVER, ofpacts);
+ encode_controller_op(ACTION_OPCODE_DHCP6_SERVER, ep->ctrl_meter_id,
+ ofpacts);
}
static void
@@ -2770,10 +2772,11 @@ format_BFD_MSG(const struct ovnact_null *a OVS_UNUSED, struct ds *s)
static void
encode_BFD_MSG(const struct ovnact_null *a OVS_UNUSED,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
- encode_controller_op(ACTION_OPCODE_BFD_MSG, ofpacts);
+ encode_controller_op(ACTION_OPCODE_BFD_MSG, ep->ctrl_meter_id,
+ ofpacts);
}
static void
@@ -2868,13 +2871,13 @@ format_DNS_LOOKUP(const struct ovnact_result *dl, struct ds *s)
static void
encode_DNS_LOOKUP(const struct ovnact_result *dl,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
struct mf_subfield dst = expr_resolve_field(&dl->dst);
size_t oc_offset = encode_start_controller_op(ACTION_OPCODE_DNS_LOOKUP,
- true, NX_CTLR_NO_METER,
+ true, ep->ctrl_meter_id,
ofpacts);
nx_put_header(ofpacts, dst.field->id, OFP15_VERSION, false);
ovs_be32 ofs = htonl(dst.ofs);
@@ -3052,13 +3055,13 @@ encode_put_nd_ra_option(const struct ovnact_gen_option *o,
static void
encode_PUT_ND_RA_OPTS(const struct ovnact_put_opts *po,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
struct mf_subfield dst = expr_resolve_field(&po->dst);
size_t oc_offset = encode_start_controller_op(
- ACTION_OPCODE_PUT_ND_RA_OPTS, true, NX_CTLR_NO_METER, ofpacts);
+ ACTION_OPCODE_PUT_ND_RA_OPTS, true, ep->ctrl_meter_id, ofpacts);
nx_put_header(ofpacts, dst.field->id, OFP15_VERSION, false);
ovs_be32 ofs = htonl(dst.ofs);
ofpbuf_put(ofpacts, &ofs, sizeof ofs);
@@ -3341,7 +3344,7 @@ format_OVNFIELD_LOAD(const struct ovnact_load *load , struct ds *s)
static void
encode_OVNFIELD_LOAD(const struct ovnact_load *load,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
const struct ovn_field *f = ovn_field_from_name(load->dst.symbol->name);
@@ -3349,7 +3352,7 @@ encode_OVNFIELD_LOAD(const struct ovnact_load *load,
case OVN_ICMP4_FRAG_MTU: {
size_t oc_offset = encode_start_controller_op(
ACTION_OPCODE_PUT_ICMP4_FRAG_MTU, true,
- NX_CTLR_NO_METER, ofpacts);
+ ep->ctrl_meter_id, ofpacts);
ofpbuf_put(ofpacts, &load->imm.value.be16_int, sizeof(ovs_be16));
encode_finish_controller_op(oc_offset, ofpacts);
break;
@@ -3357,7 +3360,7 @@ encode_OVNFIELD_LOAD(const struct ovnact_load *load,
case OVN_ICMP6_FRAG_MTU: {
size_t oc_offset = encode_start_controller_op(
ACTION_OPCODE_PUT_ICMP6_FRAG_MTU, true,
- NX_CTLR_NO_METER, ofpacts);
+ ep->ctrl_meter_id, ofpacts);
ofpbuf_put(ofpacts, &load->imm.value.be32_int, sizeof(ovs_be32));
encode_finish_controller_op(oc_offset, ofpacts);
break;
@@ -3461,7 +3464,7 @@ encode_BIND_VPORT(const struct ovnact_bind_vport *vp,
};
encode_setup_args(args, ARRAY_SIZE(args), ofpacts);
size_t oc_offset = encode_start_controller_op(ACTION_OPCODE_BIND_VPORT,
- false, NX_CTLR_NO_METER,
+ false, ep->ctrl_meter_id,
ofpacts);
ovs_be32 vp_key = htonl(vport_key);
ofpbuf_put(ofpacts, &vp_key, sizeof(ovs_be32));
@@ -3499,14 +3502,15 @@ format_HANDLE_SVC_CHECK(const struct ovnact_handle_svc_check *svc_chk,
static void
encode_HANDLE_SVC_CHECK(const struct ovnact_handle_svc_check *svc_chk,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
const struct arg args[] = {
{ expr_resolve_field(&svc_chk->port), MFF_LOG_INPORT },
};
encode_setup_args(args, ARRAY_SIZE(args), ofpacts);
- encode_controller_op(ACTION_OPCODE_HANDLE_SVC_CHECK, ofpacts);
+ encode_controller_op(ACTION_OPCODE_HANDLE_SVC_CHECK, ep->ctrl_meter_id,
+ ofpacts);
encode_restore_args(args, ARRAY_SIZE(args), ofpacts);
}
@@ -3755,7 +3759,7 @@ format_PUT_FDB(const struct ovnact_put_fdb *put_fdb, struct ds *s)
static void
encode_PUT_FDB(const struct ovnact_put_fdb *put_fdb,
- const struct ovnact_encode_params *ep OVS_UNUSED,
+ const struct ovnact_encode_params *ep,
struct ofpbuf *ofpacts)
{
const struct arg args[] = {
@@ -3763,7 +3767,7 @@ encode_PUT_FDB(const struct ovnact_put_fdb *put_fdb,
{ expr_resolve_field(&put_fdb->mac), MFF_ETH_SRC }
};
encode_setup_args(args, ARRAY_SIZE(args), ofpacts);
- encode_controller_op(ACTION_OPCODE_PUT_FDB, ofpacts);
+ encode_controller_op(ACTION_OPCODE_PUT_FDB, ep->ctrl_meter_id, ofpacts);
encode_restore_args(args, ARRAY_SIZE(args), ofpacts);
}
diff --git a/ovn-sb.ovsschema b/ovn-sb.ovsschema
index 205a30a37..609699475 100644
--- a/ovn-sb.ovsschema
+++ b/ovn-sb.ovsschema
@@ -1,7 +1,7 @@
{
"name": "OVN_Southbound",
- "version": "20.17.0",
- "cksum": "669123379 26536",
+ "version": "20.18.0",
+ "cksum": "3870294693 26668",
"tables": {
"SB_Global": {
"columns": {
@@ -109,6 +109,8 @@
"maxInteger": 65535}}},
"match": {"type": "string"},
"actions": {"type": "string"},
+ "controller_meter": {"type": {"key": {"type": "string"},
+ "min": 0, "max": 1}},
"external_ids": {
"type": {"key": "string", "value": "string",
"min": 0, "max": "unlimited"}}},
diff --git a/ovn-sb.xml b/ovn-sb.xml
index 258a12b4e..57c522db3 100644
--- a/ovn-sb.xml
+++ b/ovn-sb.xml
@@ -2441,6 +2441,12 @@ tcp.flags = RST;
</dl>
</column>
+ <column name="controller_meter">
+ The name of the meter in table <ref table="Meter"/> to be used for
+ all packets that the logical flow might send to
+ <code>ovn-controller</code>.
+ </column>
+
<column name="external_ids" key="stage-name">
Human-readable name for this flow's stage in the pipeline.
</column>
--
2.30.2
More information about the dev
mailing list