Re: [ovs-dev] [PATCH ovn 1/5] ovn-controller: Add support for Logical_Flow control meters

2021-05-24 Thread Lorenzo Bianconi
> On 20/05/2021 21:26, Mark Michelson wrote:
> > I think this patch could use some ovn-controller tests to ensure that 
> > meters configured in the SB end up being applied to the resulting 
> > controller() actions.
> > 
> > On 4/29/21 1:04 PM, Lorenzo Bianconi wrote:
> >> From: Dumitru Ceara 
> >>
> >> 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_metred' function to create a new 'ovn_flow'
> > 
> > This spelling is odd to me. I think it should be 
> > "ofctrl_add_flow_metered". I was worried when making this suggestion I 
> > was being US-centric with my spelling suggestion, but I think other 
> > variants of English also use the "meter" spelling instead of "metre" 
> > when referring to a regulating tool. Therefore, I think "metered" is 
> > preferred over "metred".
> > 
> > (Someone from Canada or from east of the Atlantic can correct me if I'm 
> > mistaken here).
> 
> Coming from Ireland, I do believe you are wrong ..
> 
> .. however, we do generally use the U.S.Americanised (notice I did not
> use a 'z' there) version of 'meter' so I think you are right.

ack, will fix it :)

Regards,
Lorenzo

> > 
> >> 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 
> >> Signed-off-by: Lorenzo Bianconi 
> >> Signed-off-by: Dumitru Ceara 
> >> ---
> >>   controller/lflow.c| 40 +++---
> >>   controller/ofctrl.c   | 54 ---
> >>   controller/ofctrl.h   | 21 ++
> >>   controller/physical.c |  7 +++--
> >>   include/ovn/actions.h |  2 ++
> >>   lib/actions.c | 66 +++
> >>   ovn-sb.ovsschema  |  6 ++--
> >>   ovn-sb.xml|  6 
> >>   8 files changed, 139 insertions(+), 63 deletions(-)
> >>
> >> diff --git a/controller/lflow.c b/controller/lflow.c
> >> index b8424e1fb..f3f901c32 100644
> >> --- a/controller/lflow.c
> >> +++ b/controller/lflow.c
> >> @@ -557,6 +557,27 @@ 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)
> >> +{
> >> +ovs_assert(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 +593,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 +623,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 +650,11 @@ add_matches_to_flow_table(const struct 
> >> sbrec_logical_flow *lflow,
> >>   }
> >>   }
> >>   if (!m->n) {
> >> -ofctrl_add_flow(l_ctx_out->flow_table, ptable,

Re: [ovs-dev] [PATCH ovn 1/5] ovn-controller: Add support for Logical_Flow control meters

2021-05-24 Thread Lorenzo Bianconi
> I think this patch could use some ovn-controller tests to ensure that meters
> configured in the SB end up being applied to the resulting controller()
> actions.
> 
> On 4/29/21 1:04 PM, Lorenzo Bianconi wrote:
> > From: Dumitru Ceara 
> > 
> > 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.

ack, I will add them in subsequent patch in order to use ovn-nbctl utilities

> > 
> > Add a new 'ofctrl_add_flow_metred' function to create a new 'ovn_flow'
> 
> This spelling is odd to me. I think it should be "ofctrl_add_flow_metered".
> I was worried when making this suggestion I was being US-centric with my
> spelling suggestion, but I think other variants of English also use the
> "meter" spelling instead of "metre" when referring to a regulating tool.
> Therefore, I think "metered" is preferred over "metred".
> 
> (Someone from Canada or from east of the Atlantic can correct me if I'm
> mistaken here).

ack, I will fix it in v2.

Regards,
Lorenzo

> 
> > 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 
> > Signed-off-by: Lorenzo Bianconi 
> > Signed-off-by: Dumitru Ceara 
> > ---
> >   controller/lflow.c| 40 +++---
> >   controller/ofctrl.c   | 54 ---
> >   controller/ofctrl.h   | 21 ++
> >   controller/physical.c |  7 +++--
> >   include/ovn/actions.h |  2 ++
> >   lib/actions.c | 66 +++
> >   ovn-sb.ovsschema  |  6 ++--
> >   ovn-sb.xml|  6 
> >   8 files changed, 139 insertions(+), 63 deletions(-)
> > 
> > diff --git a/controller/lflow.c b/controller/lflow.c
> > index b8424e1fb..f3f901c32 100644
> > --- a/controller/lflow.c
> > +++ b/controller/lflow.c
> > @@ -557,6 +557,27 @@ 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)
> > +{
> > +ovs_assert(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 +593,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 +623,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 +650,11 @@ 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_metred(l_ctx_out->flow_table, ptable,
> > +   lflow->priority,
> > +

Re: [ovs-dev] [PATCH ovn 1/5] ovn-controller: Add support for Logical_Flow control meters

2021-05-21 Thread Mark Gray
On 20/05/2021 21:26, Mark Michelson wrote:
> I think this patch could use some ovn-controller tests to ensure that 
> meters configured in the SB end up being applied to the resulting 
> controller() actions.
> 
> On 4/29/21 1:04 PM, Lorenzo Bianconi wrote:
>> From: Dumitru Ceara 
>>
>> 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_metred' function to create a new 'ovn_flow'
> 
> This spelling is odd to me. I think it should be 
> "ofctrl_add_flow_metered". I was worried when making this suggestion I 
> was being US-centric with my spelling suggestion, but I think other 
> variants of English also use the "meter" spelling instead of "metre" 
> when referring to a regulating tool. Therefore, I think "metered" is 
> preferred over "metred".
> 
> (Someone from Canada or from east of the Atlantic can correct me if I'm 
> mistaken here).

Coming from Ireland, I do believe you are wrong ..

.. however, we do generally use the U.S.Americanised (notice I did not
use a 'z' there) version of 'meter' so I think you are right.
> 
>> 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 
>> Signed-off-by: Lorenzo Bianconi 
>> Signed-off-by: Dumitru Ceara 
>> ---
>>   controller/lflow.c| 40 +++---
>>   controller/ofctrl.c   | 54 ---
>>   controller/ofctrl.h   | 21 ++
>>   controller/physical.c |  7 +++--
>>   include/ovn/actions.h |  2 ++
>>   lib/actions.c | 66 +++
>>   ovn-sb.ovsschema  |  6 ++--
>>   ovn-sb.xml|  6 
>>   8 files changed, 139 insertions(+), 63 deletions(-)
>>
>> diff --git a/controller/lflow.c b/controller/lflow.c
>> index b8424e1fb..f3f901c32 100644
>> --- a/controller/lflow.c
>> +++ b/controller/lflow.c
>> @@ -557,6 +557,27 @@ 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)
>> +{
>> +ovs_assert(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 +593,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 +623,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 +650,11 @@ 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_metred(l_ctx_out->flow_table, ptable,
>> +   lflow->

Re: [ovs-dev] [PATCH ovn 1/5] ovn-controller: Add support for Logical_Flow control meters

2021-05-20 Thread Mark Michelson
I think this patch could use some ovn-controller tests to ensure that 
meters configured in the SB end up being applied to the resulting 
controller() actions.


On 4/29/21 1:04 PM, Lorenzo Bianconi wrote:

From: Dumitru Ceara 

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_metred' function to create a new 'ovn_flow'


This spelling is odd to me. I think it should be 
"ofctrl_add_flow_metered". I was worried when making this suggestion I 
was being US-centric with my spelling suggestion, but I think other 
variants of English also use the "meter" spelling instead of "metre" 
when referring to a regulating tool. Therefore, I think "metered" is 
preferred over "metred".


(Someone from Canada or from east of the Atlantic can correct me if I'm 
mistaken here).



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 
Signed-off-by: Lorenzo Bianconi 
Signed-off-by: Dumitru Ceara 
---
  controller/lflow.c| 40 +++---
  controller/ofctrl.c   | 54 ---
  controller/ofctrl.h   | 21 ++
  controller/physical.c |  7 +++--
  include/ovn/actions.h |  2 ++
  lib/actions.c | 66 +++
  ovn-sb.ovsschema  |  6 ++--
  ovn-sb.xml|  6 
  8 files changed, 139 insertions(+), 63 deletions(-)

diff --git a/controller/lflow.c b/controller/lflow.c
index b8424e1fb..f3f901c32 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -557,6 +557,27 @@ 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)
+{
+ovs_assert(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 +593,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 +623,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 +650,11 @@ 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_metred(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 +672,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,
- 

[ovs-dev] [PATCH ovn 1/5] ovn-controller: Add support for Logical_Flow control meters

2021-04-29 Thread Lorenzo Bianconi
From: Dumitru Ceara 

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_metred' 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 
Signed-off-by: Lorenzo Bianconi 
Signed-off-by: Dumitru Ceara 
---
 controller/lflow.c| 40 +++---
 controller/ofctrl.c   | 54 ---
 controller/ofctrl.h   | 21 ++
 controller/physical.c |  7 +++--
 include/ovn/actions.h |  2 ++
 lib/actions.c | 66 +++
 ovn-sb.ovsschema  |  6 ++--
 ovn-sb.xml|  6 
 8 files changed, 139 insertions(+), 63 deletions(-)

diff --git a/controller/lflow.c b/controller/lflow.c
index b8424e1fb..f3f901c32 100644
--- a/controller/lflow.c
+++ b/controller/lflow.c
@@ -557,6 +557,27 @@ 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)
+{
+ovs_assert(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 +593,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 +623,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 +650,11 @@ 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_metred(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 +672,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..575dcd625 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 *de