> 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 <[email protected]>
> >>
> >> 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 <[email protected]>
> >> Signed-off-by: Lorenzo Bianconi <[email protected]>
> >> Signed-off-by: Dumitru Ceara <[email protected]>
> >> ---
> >>   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 *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);
> >> @@ -1010,8 +1012,9 @@ link_flow_to_sb(struct ovn_desired_flow_table 
> >> *flow_table,
> >>   /* Flow table interfaces to the rest of ovn-controller. */
> >>   
> >>   /* Adds a flow to 'desired_flows' with the specified 'match' and 
> >> 'actions' to
> >> - * the OpenFlow table numbered 'table_id' with the given 'priority' and
> >> - * OpenFlow 'cookie'.  The caller retains ownership of 'match' and 
> >> 'actions'.
> >> + * the OpenFlow table numbered 'table_id' with the given 'priority', 
> >> OpenFlow
> >> + * 'cookie' and 'meter_id'. The caller retains ownership of 'match' and
> >> + * 'actions'.
> >>    *
> >>    * The flow is also linked to the sb_uuid that generates it.
> >>    *
> >> @@ -1020,15 +1023,15 @@ link_flow_to_sb(struct ovn_desired_flow_table 
> >> *flow_table,
> >>    *
> >>    * The caller should initialize its own hmap to hold the flows. */
> >>   void
> >> -ofctrl_check_and_add_flow(struct ovn_desired_flow_table *flow_table,
> >> -                          uint8_t table_id, uint16_t priority,
> >> -                          uint64_t cookie, const struct match *match,
> >> -                          const struct ofpbuf *actions,
> >> -                          const struct uuid *sb_uuid,
> >> -                          bool log_duplicate_flow)
> >> +ofctrl_check_and_add_flow_metred(struct ovn_desired_flow_table 
> >> *flow_table,
> >> +                                 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, 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) {
> >> @@ -1056,8 +1059,18 @@ ofctrl_add_flow(struct ovn_desired_flow_table 
> >> *desired_flows,
> >>                   const struct match *match, const struct ofpbuf *actions,
> >>                   const struct uuid *sb_uuid)
> >>   {
> >> -    ofctrl_check_and_add_flow(desired_flows, table_id, priority, cookie,
> >> -                              match, actions, sb_uuid, true);
> >> +    ofctrl_add_flow_metred(desired_flows, table_id, priority, cookie,
> >> +                           match, actions, sb_uuid, NX_CTLR_NO_METER);
> >> +}
> >> +
> >> +void
> >> +ofctrl_add_flow_metred(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_metred(desired_flows, table_id, priority, 
> >> cookie,
> >> +                                     match, actions, sb_uuid, meter_id, 
> >> true);
> >>   }
> >>   
> >>   /* Either add a new flow, or append actions on an existing flow. If the
> >> @@ -1068,12 +1081,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 +1293,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 +1302,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 +1317,8 @@ 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 +1344,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 +1371,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..018d781a2 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_metred(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).
> >> @@ -108,11 +116,12 @@ void ovn_desired_flow_table_init(struct 
> >> ovn_desired_flow_table *);
> >>   void ovn_desired_flow_table_clear(struct ovn_desired_flow_table *);
> >>   void ovn_desired_flow_table_destroy(struct ovn_desired_flow_table *);
> >>   
> >> -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);
> >> +void ofctrl_check_and_add_flow_metred(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 *, 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..82bf9358a 100644
> >> --- a/controller/physical.c
> >> +++ b/controller/physical.c
> >> @@ -838,7 +838,7 @@ put_local_common_flows(uint32_t dp_key, uint32_t 
> >> port_key,
> >>            * If a parent port has multiple child ports, then this if 
> >> condition
> >>            * will be hit multiple times, but we want to add only one flow.
> >>            * ofctrl_add_flow() logs a warning message for duplicate flows.
> >> -         * So use the function 'ofctrl_check_and_add_flow' which doesn't
> >> +         * So use the function 'ofctrl_check_and_add_flow_metred' which 
> >> doesn't
> >>            * log a warning.
> >>            *
> >>            * Other option is to add this flow for all the ports which are 
> >> not
> >> @@ -857,8 +857,9 @@ put_local_common_flows(uint32_t dp_key, uint32_t 
> >> port_key,
> >>           put_load(ofp_to_u16(OFPP_NONE), MFF_IN_PORT, 0, 16, ofpacts_p);
> >>           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);
> >> +        ofctrl_check_and_add_flow_metred(flow_table, OFTABLE_SAVE_INPORT, 
> >> 100,
> >> +                                         0, &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>
> >>
> > 
> > _______________________________________________
> > dev mailing list
> > [email protected]
> > https://mail.openvswitch.org/mailman/listinfo/ovs-dev
> > 
> 
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to