With small nits below:

Acked-by: Jarno Rajahalme <ja...@ovn.org>

> On Apr 14, 2017, at 12:46 PM, Andy Zhou <az...@ovn.org> wrote:
> 
> Allow action upcall meters, i.e. slowpath and controller meters,
> to be added and displayed.
> 
> Keep track of datapath meter ID of those action upcall meters in
> ofproto to aid action translation. Later patches will make use of them.
> 
> Signed-off-by: Andy Zhou <az...@ovn.org>
> ---
> lib/ofp-print.c            | 33 ++++++++++++++++++++++++++---
> ofproto/ofproto-provider.h |  4 ++++
> ofproto/ofproto.c          | 52 ++++++++++++++++++++++++++++++++++++++++++----
> 3 files changed, 82 insertions(+), 7 deletions(-)
> 
> diff --git a/lib/ofp-print.c b/lib/ofp-print.c
> index a8cdfcbf20b1..140af05950b7 100644
> --- a/lib/ofp-print.c
> +++ b/lib/ofp-print.c
> @@ -1333,11 +1333,36 @@ ofp_print_meter_band(struct ds *s, uint16_t flags,
> }
> 
> static void
> +ofp_print_meter_id(struct ds *s, uint32_t meter_id, char seperator)
> +{
> +    if (meter_id <= OFPM13_MAX) {
> +        ds_put_format(s, "meter%c%"PRIu32, seperator, meter_id);
> +    } else {
> +        const char *name;
> +        switch (meter_id) {
> +        case OFPM13_SLOWPATH:
> +            name = "slowpath";
> +            break;
> +        case OFPM13_CONTROLLER:
> +            name = "controller";
> +            break;
> +        case OFPM13_ALL:
> +            name = "ALL”;

We require lower case “all” when parsing, so better print that way also.

> +            break;
> +        default:
> +            name = "unknown";
> +        }
> +        ds_put_format(s, "meter%c%s", seperator, name);
> +    }
> +}
> +
> +static void
> ofp_print_meter_stats(struct ds *s, const struct ofputil_meter_stats *ms)
> {
>     uint16_t i;
> 
> -    ds_put_format(s, "meter:%"PRIu32" ", ms->meter_id);
> +    ofp_print_meter_id(s, ms->meter_id, ':');
> +    ds_put_char(s, ' ');
>     ds_put_format(s, "flow_count:%"PRIu32" ", ms->flow_count);
>     ds_put_format(s, "packet_in_count:%"PRIu64" ", ms->packet_in_count);
>     ds_put_format(s, "byte_in_count:%"PRIu64" ", ms->byte_in_count);
> @@ -1358,7 +1383,8 @@ ofp_print_meter_config(struct ds *s, const struct 
> ofputil_meter_config *mc)
> {
>     uint16_t i;
> 
> -    ds_put_format(s, "meter=%"PRIu32" ", mc->meter_id);
> +    ofp_print_meter_id(s, mc->meter_id, '=');
> +    ds_put_char(s, ' ');
> 
>     ofp_print_meter_flags(s, mc->flags);
> 
> @@ -1412,8 +1438,9 @@ ofp_print_meter_stats_request(struct ds *s, const 
> struct ofp_header *oh)
>     uint32_t meter_id;
> 
>     ofputil_decode_meter_request(oh, &meter_id);
> +    ds_put_char(s, ' ');
> 
> -    ds_put_format(s, " meter=%"PRIu32, meter_id);
> +    ofp_print_meter_id(s, meter_id, '=');
> }
> 
> static const char *
> diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
> index 000326d7f79d..688a9e5d32eb 100644
> --- a/ofproto/ofproto-provider.h
> +++ b/ofproto/ofproto-provider.h
> @@ -112,6 +112,10 @@ struct ofproto {
>     /* Meter table.  */
>     struct ofputil_meter_features meter_features;
>     struct hmap meters;             /* uint32_t indexed 'struct meter *'.  */
> +    uint32_t slowpath_meter_id;     /* Datapath slowpath meter.  UINT32_MAX
> +                                       if not defined.  */
> +    uint32_t controller_meter_id;   /* Datapath controller meter. UINT32_MAX
> +                                       if not defined.  */
> 
>     /* OpenFlow connections. */
>     struct connmgr *connmgr;
> diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
> index 8c4c7e67f213..abbb849a384b 100644
> --- a/ofproto/ofproto.c
> +++ b/ofproto/ofproto.c
> @@ -568,6 +568,8 @@ ofproto_create(const char *datapath_name, const char 
> *datapath_type,
>         memset(&ofproto->meter_features, 0, sizeof ofproto->meter_features);
>     }
>     hmap_init(&ofproto->meters);
> +    ofproto->slowpath_meter_id = UINT32_MAX;
> +    ofproto->controller_meter_id = UINT32_MAX;
> 
>     /* Set the initial tables version. */
>     ofproto_bump_tables_version(ofproto);
> @@ -6232,9 +6234,33 @@ ofproto_get_meter(const struct ofproto *ofproto, 
> uint32_t meter_id)
>     return NULL;
> }
> 
> +static uint32_t *
> +ofproto_upcall_meter_ptr(struct ofproto *ofproto, uint32_t meter_id)
> +{
> +    switch(meter_id) {
> +    case OFPM13_SLOWPATH:
> +        return &ofproto->slowpath_meter_id;
> +        break;
> +    case OFPM13_CONTROLLER:
> +        return &ofproto->controller_meter_id;
> +        break;
> +    case OFPM13_ALL:
> +        OVS_NOT_REACHED();
> +    default:
> +        return NULL;
> +    }
> +}
> +
> static void
> ofproto_add_meter(struct ofproto *ofproto, struct meter *meter)
> {
> +    uint32_t *upcall_meter_ptr = ofproto_upcall_meter_ptr(ofproto, 
> meter->id);
> +
> +    /* Cache datapath meter IDs of special meters. */
> +    if (upcall_meter_ptr) {
> +        *upcall_meter_ptr = meter->provider_meter_id.uint32;
> +    }
> +
>     hmap_insert(&ofproto->meters, &meter->node, hash_int(meter->id, 0));
> }
> 
> @@ -6248,7 +6274,7 @@ static bool
> ofproto_fix_meter_action(const struct ofproto *ofproto,
>                          struct ofpact_meter *ma)
> {
> -    if (ma->meter_id && ma->meter_id <= ofproto->meter_features.max_meters) {
> +    if (ma->meter_id) {

This change would better be placed with patch 1/5?

>         const struct meter *meter = ofproto_get_meter(ofproto, ma->meter_id);
> 
>         if (meter && meter->provider_meter_id.uint32 != UINT32_MAX) {
> @@ -6306,6 +6332,12 @@ static void
> meter_destroy(struct ofproto *ofproto, struct meter *meter)
>     OVS_REQUIRES(ofproto_mutex)
> {
> +    uint32_t *upcall_meter_ptr;
> +    upcall_meter_ptr = ofproto_upcall_meter_ptr(ofproto, meter->id);
> +    if (upcall_meter_ptr) {
> +        *upcall_meter_ptr = UINT32_MAX;
> +    }
> +
>     if (!ovs_list_is_empty(&meter->rules)) {
>         struct rule_collection rules;
>         struct rule *rule;
> @@ -6438,12 +6470,24 @@ handle_meter_mod(struct ofconn *ofconn, const struct 
> ofp_header *oh)
> 
>     if (mm.command != OFPMC13_DELETE) {
>         /* Fails also when meters are not implemented by the provider. */
> -        if (meter_id == 0 || meter_id > OFPM13_MAX) {
> +        if (ofproto->meter_features.max_meters == 0) {
>             error = OFPERR_OFPMMFC_INVALID_METER;
>             goto exit_free_bands;
> -        } else if (meter_id > ofproto->meter_features.max_meters) {
> -            error = OFPERR_OFPMMFC_OUT_OF_METERS;
> +        }
> +
> +        if (meter_id == 0) {
> +            error = OFPERR_OFPMMFC_INVALID_METER;
>             goto exit_free_bands;
> +        } else if (meter_id > OFPM13_MAX) {
> +            switch(meter_id) {
> +            case OFPM13_SLOWPATH:
> +            case OFPM13_CONTROLLER:
> +                break;
> +            case OFPM13_ALL:
> +            default:
> +                error = OFPERR_OFPMMFC_INVALID_METER;
> +                goto exit_free_bands;
> +            }
>         }
>         if (mm.meter.n_bands > ofproto->meter_features.max_bands) {
>             error = OFPERR_OFPMMFC_OUT_OF_BANDS;
> -- 
> 1.8.3.1
> 
> _______________________________________________
> dev mailing list
> d...@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev

_______________________________________________
dev mailing list
d...@openvswitch.org
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to